@lpdjs/firestore-repo-service 2.1.2 → 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/shared/zod-compat.ts","../../../src/servers/admin/form-gen.ts","../../../src/servers/admin/components/cell-value.tsx","../../../src/servers/admin/components/client-script.raw.js","../../../src/servers/admin/components/client-script.tsx","../../../src/servers/admin/components/shell.tsx","../../../src/servers/admin/components/dashboard.tsx","../../../src/servers/admin/components/filter-bar.tsx","../../../src/servers/admin/components/form.tsx","../../../src/servers/admin/components/list.tsx","../../../src/servers/admin/renderer.ts","../../../src/servers/admin/handlers.ts","../../../src/servers/admin/router.ts","../../../src/servers/admin/index.ts"],"names":["TYPE_MAP","getTypeName","schema","s","v4Type","v3Type","getInnerType","getArrayElementType","getDefaultValue","v","getShape","getEnumValues","getNativeEnumValues","getLiteralValue","getStringChecks","kinds","v4Checks","c","v3Checks","toLabel","name","unwrap","inner","required","nullable","defaultValue","tn","zodToFields","namePrefix","shape","fieldName","fieldSchema","zodFieldToDescriptor","rawName","label","checks","isEmail","isUrl","values","enumObj","value","nested","elSchema","elInner","elTn","arrayElementType","arrayElementOptions","arrayElementFields","renderField","field","depth","indent","id","nameAttr","requiredAttr","isNullValue","defaultStr","nullToggle","input","sel3","e","o","renderArrayField","subFields","f","isObject","items","itemsHtml","item","renderObjectItem","renderPrimitiveItem","templateHtml","strVal","inputHtml","obj","val","renderForm","fields","action","method","submitLabel","fieldsHtml","CellDate","jsx","CellValue","jsxs","i","entries","k","Fragment","str","client_script_raw_default","ClientScript","renderHtml","element","renderToString","PageShell","opts","children","title","breadcrumb","flash","basePath","renderDashboardJsx","repos","r","OPS_TEXT","OPS_NUMERIC","OPS_ARRAY","opsForType","zodType","FilterValueInput","col","active","isAny","FilterBar","columnMeta","activeFilters","activeMap","hasActive","filterable","ops","currentOp","renderFormPageJsx","repoName","formHtml","mode","docId","crumbs","baseParams","filters","sort","pageSize","p","paginationHref","cursor","dir","sortHref","current","pageSizeHref","newPs","renderListJsx","docs","columns","pagination","allowDelete","relationalMeta","sortState","currentPageSize","listUrl","createUrl","ps","isSorted","arrow","m","doc","rowIdx","editUrl","deleteUrl","ci","mi","rawVal","href","renderDashboard","renderList","renderFormPage","_idChars","generateFirestoreId","extractPathArgs","pathKey","fullPath","segments","args","fetchDocById","entry","docKey","getMethod","sendHtml","res","html","status","redirect","to","parseFormBody","raw","result","key","zodField","resolveTypeName","subRaw","hasDotKeys","innerSchema","itn","toDatetimeLocal","date","d","pad","n","prefillFromDoc","prefix","fullKey","innerTn","dtLocal","applyPrefill","prefilled","parseFilters","query","validFields","validOps","opRaw","op","filtersToWhere","coerce","arr","buildColumnMeta","fullName","subShape","resolveZodAtPath","path","parts","part","getMutableSchema","topLevel","dotGroups","dot","parent","child","picked","z","getLinkBase","req","staticBasePath","base","project","region","target","service","host","createAdminHandlers","registry","lb","cursorStr","sortField","sortDir","psRaw","allColumns","filterableColumns","out","resolved","whereFilters","cursorSnapshot","colRef","nextCursorId","prevCursorId","createSchema","actionUrl","rawBody","parsed","validation","errorMsg","data","missingKeys","parentIds","err","createSchema2","mutableSchema","pathArgs","mutableSchema2","compilePath","paramNames","src","_match","extractPath","idx","MiniRouter","_req","middleware","handler","pattern","matchedRoute","params","route","enrichedReq","finalHandler","index","next","mw","readRawBody","parseUrlEncoded","body","pair","existing","createAdminServer","options","parseBody","auth","extraMiddleware","httpsOptions","cfg","resolvedSchema","filterableFields","mutableFields","createFields","fc","roles","role","parentKeys","pk","repoRelKeys","meta","rel","handlers","router","_res","contentType","realm","expected"],"mappings":"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AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACKS,CAAA,CAHF,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","file":"index.cjs","sourcesContent":["/**\n * Zod introspection utilities — compatible with Zod 4.\n *\n * Centralizes all internal `_zod.def` accesses so the rest of the codebase\n * never touches Zod internals directly. If a future Zod version changes\n * the internal layout, only this file needs updating.\n */\n\nimport type { z } from \"zod\";\n\n// ---------------------------------------------------------------------------\n// Type-name resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Canonical Zod type names used in the codebase.\n * These match the **Zod 3** naming convention (e.g. \"ZodString\") that the\n * form-gen / admin handlers already rely on, so we don't need to rewrite\n * every `case \"ZodString\":` branch.\n */\ntype ZodTypeName =\n | \"ZodString\"\n | \"ZodNumber\"\n | \"ZodBigInt\"\n | \"ZodBoolean\"\n | \"ZodDate\"\n | \"ZodEnum\"\n | \"ZodNativeEnum\"\n | \"ZodLiteral\"\n | \"ZodObject\"\n | \"ZodArray\"\n | \"ZodOptional\"\n | \"ZodNullable\"\n | \"ZodDefault\"\n | \"ZodCoerce\"\n | \"ZodUnion\"\n | \"ZodUndefined\"\n | \"ZodUnknown\"\n | \"ZodAny\"\n | \"ZodRecord\"\n | string;\n\n/**\n * Map from Zod 4 `_zod.def.type` (lowercase) → Zod 3 `_def.typeName` format.\n * Any key not in this map is capitalised as `Zod${Capitalised}`.\n */\nconst TYPE_MAP: Record<string, ZodTypeName> = {\n string: \"ZodString\",\n number: \"ZodNumber\",\n bigint: \"ZodBigInt\",\n boolean: \"ZodBoolean\",\n date: \"ZodDate\",\n enum: \"ZodEnum\",\n nativeEnum: \"ZodNativeEnum\",\n literal: \"ZodLiteral\",\n object: \"ZodObject\",\n array: \"ZodArray\",\n optional: \"ZodOptional\",\n nullable: \"ZodNullable\",\n default: \"ZodDefault\",\n coerce: \"ZodCoerce\",\n union: \"ZodUnion\",\n undefined: \"ZodUndefined\",\n unknown: \"ZodUnknown\",\n any: \"ZodAny\",\n record: \"ZodRecord\",\n};\n\n/**\n * Get the canonical type name of a Zod schema.\n *\n * Works with both Zod 3 (`_def.typeName`) and Zod 4 (`_zod.def.type`).\n * Returns names in Zod-3 style (\"ZodString\", \"ZodObject\" …) for\n * backward-compatible switch/case usage.\n */\nexport function getTypeName(schema: z.ZodType): ZodTypeName {\n const s = schema as any;\n\n // Zod 4 path\n const v4Type: string | undefined = s._zod?.def?.type;\n if (v4Type)\n return (\n TYPE_MAP[v4Type] ??\n `Zod${v4Type.charAt(0).toUpperCase()}${v4Type.slice(1)}`\n );\n\n // Zod 3 fallback\n const v3Type: string | undefined = s._def?.typeName;\n if (v3Type) return v3Type;\n\n return \"\";\n}\n\n// ---------------------------------------------------------------------------\n// Unwrapping wrappers (Optional / Nullable / Default)\n// ---------------------------------------------------------------------------\n\n/**\n * Get the inner schema from a wrapper type (Optional / Nullable / Default).\n */\nexport function getInnerType(schema: z.ZodType): z.ZodType | undefined {\n const s = schema as any;\n\n // Zod 4: _zod.def.innerType\n if (s._zod?.def?.innerType) return s._zod.def.innerType;\n\n // Zod 3 compat: _def.innerType\n if (s._def?.innerType) return s._def.innerType;\n\n return undefined;\n}\n\n/**\n * Get the **element schema** from a `ZodArray`.\n * Returns `undefined` for non-array schemas.\n */\nexport function getArrayElementType(\n schema: z.ZodType,\n): z.ZodType | undefined {\n const s = schema as any;\n\n // Zod 4: _zod.def.element\n if (s._zod?.def?.element) return s._zod.def.element;\n\n // Zod 3: _def.type (ZodArray stores element schema in _def.type)\n if (s._def?.type) return s._def.type;\n\n return undefined;\n}\n\n/**\n * Returns the list of **required** (non-optional) top-level keys of a ZodObject.\n * A key is required when its schema is NOT wrapped in ZodOptional.\n * ZodNullable / ZodDefault fields are still considered required — they must be present.\n */\nexport function getRequiredSchemaKeys(schema: z.ZodObject<any>): string[] {\n const required: string[] = [];\n for (const [key, fieldSchema] of Object.entries(schema.shape)) {\n const typeName = getTypeName(fieldSchema as z.ZodType);\n if (typeName !== \"ZodOptional\") {\n required.push(key);\n }\n }\n return required;\n}\n\n/**\n * Get the default value for a ZodDefault schema.\n * In Zod 3 this was `_def.defaultValue()` (function). In Zod 4 it's a direct value.\n */\nexport function getDefaultValue(schema: z.ZodType): unknown {\n const s = schema as any;\n\n // Zod 4\n if (s._zod?.def?.defaultValue !== undefined) return s._zod.def.defaultValue;\n\n // Zod 3 compat\n const v = s._def?.defaultValue;\n if (typeof v === \"function\") return v();\n return v;\n}\n\n// ---------------------------------------------------------------------------\n// Object shape\n// ---------------------------------------------------------------------------\n\n/**\n * Get the shape of a ZodObject schema (Record<string, ZodType>).\n * Handles both Zod 3 (`_def.shape()` function) and Zod 4 (`.shape` property).\n */\nexport function getShape(schema: z.ZodType): Record<string, z.ZodType> {\n const s = schema as any;\n\n // Direct `.shape` property (Zod 3 & 4 for ZodObject instances)\n if (s.shape && typeof s.shape === \"object\") return s.shape;\n\n // Zod 4: _zod.def.shape\n if (s._zod?.def?.shape && typeof s._zod.def.shape === \"object\")\n return s._zod.def.shape;\n\n // Zod 3 fallback: _def.shape() or _def.shape\n if (s._def?.shape) {\n return typeof s._def.shape === \"function\" ? s._def.shape() : s._def.shape;\n }\n\n return {};\n}\n\n// ---------------------------------------------------------------------------\n// Enum / Literal values\n// ---------------------------------------------------------------------------\n\n/**\n * Get the values of a ZodEnum schema as a string[].\n */\nexport function getEnumValues(schema: z.ZodType): string[] {\n const s = schema as any;\n\n // Zod 4: `.options` or `_zod.def.entries`\n if (Array.isArray(s.options)) return s.options;\n if (s._zod?.def?.entries)\n return Object.values(s._zod.def.entries) as string[];\n\n // Zod 3: `_def.values`\n if (Array.isArray(s._def?.values)) return s._def.values;\n\n return [];\n}\n\n/**\n * Get the value object of a ZodNativeEnum schema.\n */\nexport function getNativeEnumValues(\n schema: z.ZodType,\n): Record<string, unknown> {\n const s = schema as any;\n\n // Zod 4: `_zod.def.entries` or `.enum`\n if (s._zod?.def?.entries) return s._zod.def.entries;\n if (s.enum && typeof s.enum === \"object\") return s.enum;\n\n // Zod 3: `_def.values`\n if (s._def?.values && typeof s._def.values === \"object\") return s._def.values;\n\n return {};\n}\n\n/**\n * Get the value of a ZodLiteral schema.\n */\nexport function getLiteralValue(schema: z.ZodType): unknown {\n const s = schema as any;\n\n // Zod 4: `_zod.def.values[0]`\n if (Array.isArray(s._zod?.def?.values)) return s._zod.def.values[0];\n\n // Zod 3: `_def.value`\n return s._def?.value;\n}\n\n// ---------------------------------------------------------------------------\n// String checks\n// ---------------------------------------------------------------------------\n\n/**\n * Get relevant \"check kinds\" from a ZodString schema.\n * Returns an array of kind strings: \"email\", \"url\", etc.\n */\nexport function getStringChecks(schema: z.ZodType): string[] {\n const s = schema as any;\n const kinds: string[] = [];\n\n // Zod 4: checks with `.format` field\n const v4Checks: any[] | undefined = s._zod?.def?.checks;\n if (Array.isArray(v4Checks)) {\n for (const c of v4Checks) {\n if (c.format) kinds.push(c.format);\n }\n if (kinds.length > 0) return kinds;\n }\n\n // Zod 3: _def.checks with `.kind` field\n const v3Checks: any[] | undefined = s._def?.checks;\n if (Array.isArray(v3Checks)) {\n for (const c of v3Checks) {\n if (c.kind) kinds.push(c.kind);\n }\n }\n\n return kinds;\n}\n","/**\n * Zod-to-HTML form generator.\n * Inspects a Zod schema's `_def` to produce typed HTML `<input>` / `<select>`\n * elements — no extra dependencies needed.\n *\n * Supported Zod types:\n * ZodString, ZodNumber, ZodBoolean, ZodDate, ZodEnum,\n * ZodOptional, ZodNullable, ZodDefault, ZodObject, ZodArray, ZodLiteral\n *\n * For ZodObject fields, nested sections are rendered with indentation.\n * For ZodArray and unknown types, a `<textarea>` with JSON hint is used.\n *\n * @example\n * ```typescript\n * import { zodToFields, renderForm } from \"@lpdjs/firestore-repo-service/servers/admin\";\n *\n * // Convert Zod schema to field descriptors\n * const schema = z.object({\n * name: z.string(),\n * email: z.string().email(),\n * age: z.number().optional(),\n * role: z.enum([\"admin\", \"user\"]),\n * isActive: z.boolean().default(true),\n * address: z.object({\n * street: z.string(),\n * city: z.string(),\n * }),\n * });\n *\n * const fields = zodToFields(schema);\n * // Returns:\n * // [\n * // { name: \"name\", type: \"text\", required: true, ... },\n * // { name: \"email\", type: \"text\", required: true, hint: \"email\", ... },\n * // { name: \"age\", type: \"number\", required: false, ... },\n * // { name: \"role\", type: \"select\", options: [\"admin\", \"user\"], ... },\n * // { name: \"isActive\", type: \"checkbox\", defaultValue: true, ... },\n * // { name: \"address\", nested: [...], ... },\n * // ]\n *\n * // Render form HTML\n * const html = renderForm(fields, \"create\", {\n * name: \"John\",\n * email: \"john@example.com\",\n * });\n *\n * // Render single field\n * const fieldHtml = renderField(fields[0], { name: \"Jane\" });\n * ```\n */\n\nimport type { z } from \"zod\";\nimport {\n getArrayElementType,\n getDefaultValue,\n getEnumValues,\n getInnerType,\n getLiteralValue,\n getNativeEnumValues,\n getShape,\n getStringChecks,\n getTypeName,\n} from \"../../shared/zod-compat\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface FieldDescriptor {\n name: string;\n label: string;\n type:\n | \"text\"\n | \"number\"\n | \"checkbox\"\n | \"datetime-local\"\n | \"select\"\n | \"textarea\";\n required: boolean;\n nullable: boolean;\n options?: string[]; // for select\n defaultValue?: unknown;\n nested?: FieldDescriptor[]; // for objects\n hint?: string;\n /** For array fields: the element input type */\n arrayElementType?:\n | \"text\"\n | \"number\"\n | \"checkbox\"\n | \"select\"\n | \"datetime-local\"\n | \"object\";\n /** For enum arrays: the allowed values */\n arrayElementOptions?: string[];\n /** For object arrays: the field descriptors for one element */\n arrayElementFields?: FieldDescriptor[];\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Convert camelCase / snake_case to \"Human Label\" */\nfunction toLabel(name: string): string {\n return name\n .replace(/([A-Z])/g, \" $1\")\n .replace(/_/g, \" \")\n .replace(/^\\s/, \"\")\n .replace(/^./, (c) => c.toUpperCase());\n}\n\n/** Unwrap ZodOptional / ZodNullable / ZodDefault to the inner schema */\nfunction unwrap(schema: z.ZodType): {\n inner: z.ZodType;\n required: boolean;\n nullable: boolean;\n defaultValue: unknown;\n} {\n let inner: z.ZodType = schema;\n let required = true;\n let nullable = false;\n let defaultValue: unknown = undefined;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const tn = getTypeName(inner);\n if (tn === \"ZodOptional\") {\n required = false;\n inner = getInnerType(inner)!;\n } else if (tn === \"ZodNullable\") {\n required = false;\n nullable = true;\n inner = getInnerType(inner)!;\n } else if (tn === \"ZodDefault\") {\n required = false;\n defaultValue = getDefaultValue(inner);\n inner = getInnerType(inner)!;\n } else {\n break;\n }\n }\n\n return { inner, required, nullable, defaultValue };\n}\n\n// ---------------------------------------------------------------------------\n// Core introspection\n// ---------------------------------------------------------------------------\n\nexport function zodToFields(\n schema: z.ZodType,\n namePrefix = \"\",\n): FieldDescriptor[] {\n const tn = getTypeName(schema);\n\n if (tn === \"ZodObject\") {\n const shape: Record<string, z.ZodType> = getShape(schema);\n return Object.entries(shape).map(([fieldName, fieldSchema]) =>\n zodFieldToDescriptor(\n namePrefix ? `${namePrefix}.${fieldName}` : fieldName,\n fieldName,\n fieldSchema,\n ),\n );\n }\n\n // If the root schema is not an object, treat it as a single field\n return [\n zodFieldToDescriptor(namePrefix || \"value\", namePrefix || \"value\", schema),\n ];\n}\n\nfunction zodFieldToDescriptor(\n name: string,\n rawName: string,\n schema: z.ZodType,\n): FieldDescriptor {\n const { inner, required, nullable, defaultValue } = unwrap(schema);\n const tn = getTypeName(inner);\n const label = toLabel(rawName.split(\".\").pop() ?? rawName);\n\n switch (tn) {\n case \"ZodString\": {\n const checks = getStringChecks(inner);\n const isEmail = checks.includes(\"email\");\n const isUrl = checks.includes(\"url\");\n return {\n name,\n label,\n type: \"text\",\n required,\n nullable,\n defaultValue,\n hint: isEmail ? \"email\" : isUrl ? \"url\" : undefined,\n };\n }\n\n case \"ZodNumber\":\n case \"ZodBigInt\":\n return { name, label, type: \"number\", required, nullable, defaultValue };\n\n case \"ZodBoolean\":\n return {\n name,\n label,\n type: \"checkbox\",\n required,\n nullable,\n defaultValue,\n };\n\n case \"ZodDate\":\n case \"ZodCoerce\":\n return {\n name,\n label,\n type: \"datetime-local\",\n required,\n nullable,\n defaultValue,\n };\n\n case \"ZodEnum\": {\n const values = getEnumValues(inner);\n return {\n name,\n label,\n type: \"select\",\n required,\n nullable,\n defaultValue,\n options: values,\n };\n }\n\n case \"ZodNativeEnum\": {\n const enumObj = getNativeEnumValues(inner);\n const values = Object.values(enumObj).filter(\n (v) => typeof v === \"string\",\n ) as string[];\n return {\n name,\n label,\n type: \"select\",\n required,\n nullable,\n defaultValue,\n options: values,\n };\n }\n\n case \"ZodLiteral\": {\n const value = String(getLiteralValue(inner) ?? \"\");\n return {\n name,\n label,\n type: \"select\",\n required,\n nullable,\n defaultValue,\n options: [value],\n };\n }\n\n case \"ZodObject\": {\n const nested = zodToFields(inner, name);\n return {\n name,\n label,\n type: \"textarea\",\n required,\n nullable,\n defaultValue,\n nested,\n hint: \"JSON object\",\n };\n }\n\n case \"ZodArray\": {\n const elSchema = getArrayElementType(inner);\n if (!elSchema) {\n return {\n name,\n label,\n type: \"textarea\",\n required,\n nullable,\n defaultValue,\n hint: \"JSON array\",\n };\n }\n const { inner: elInner } = unwrap(elSchema);\n const elTn = getTypeName(elInner);\n\n let arrayElementType: FieldDescriptor[\"arrayElementType\"];\n let arrayElementOptions: string[] | undefined;\n let arrayElementFields: FieldDescriptor[] | undefined;\n\n switch (elTn) {\n case \"ZodString\":\n arrayElementType = \"text\";\n break;\n case \"ZodNumber\":\n case \"ZodBigInt\":\n arrayElementType = \"number\";\n break;\n case \"ZodBoolean\":\n arrayElementType = \"checkbox\";\n break;\n case \"ZodDate\":\n arrayElementType = \"datetime-local\";\n break;\n case \"ZodEnum\":\n arrayElementType = \"select\";\n arrayElementOptions = getEnumValues(elInner);\n break;\n case \"ZodNativeEnum\":\n arrayElementType = \"select\";\n arrayElementOptions = Object.values(\n getNativeEnumValues(elInner),\n ).filter((v) => typeof v === \"string\") as string[];\n break;\n case \"ZodObject\":\n arrayElementType = \"object\";\n arrayElementFields = zodToFields(elInner);\n break;\n default:\n // Unknown element type → JSON textarea fallback\n return {\n name,\n label,\n type: \"textarea\",\n required,\n nullable,\n defaultValue,\n hint: \"JSON array\",\n };\n }\n\n return {\n name,\n label,\n type: \"textarea\",\n required,\n nullable,\n defaultValue,\n arrayElementType,\n arrayElementOptions,\n arrayElementFields,\n };\n }\n\n default:\n return {\n name,\n label,\n type: \"textarea\",\n required,\n nullable,\n defaultValue,\n hint: \"JSON\",\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// HTML generation — DaisyUI + Tailwind classes\n// ---------------------------------------------------------------------------\n\nexport function renderField(field: FieldDescriptor, depth = 0): string {\n const indent = depth > 0 ? `ml-${depth * 4}` : \"\";\n const id = `field_${field.name.replace(/\\./g, \"__\")}`;\n const nameAttr = field.name;\n const requiredAttr = field.required ? \" required\" : \"\";\n // \"__null__\" is the sentinel value used when a nullable field is set to null\n const isNullValue = field.defaultValue === \"__null__\";\n const defaultStr =\n !isNullValue && field.defaultValue != null\n ? String(field.defaultValue)\n : \"\";\n\n // Null toggle — rendered inline to the right of the input for nullable non-checkbox fields\n const nullToggle =\n field.nullable && field.type !== \"checkbox\"\n ? `<span class=\"flex items-center gap-1 shrink-0\">\n <input type=\"hidden\" id=\"${id}__isnull\" name=\"${nameAttr}__isnull\" value=\"${isNullValue ? \"1\" : \"\"}\">\n <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\">\n <input type=\"checkbox\" class=\"checkbox checkbox-xs\" ${isNullValue ? \"checked\" : \"\"}\n onchange=\"(function(cb){\n var inp = document.getElementById('${id}');\n var h = document.getElementById('${id}__isnull');\n if (cb.checked) { inp.disabled=true; inp.style.opacity='0.35'; h.value='1'; }\n else { inp.disabled=false; inp.style.opacity=''; h.value=''; }\n })(this)\">\n <span>null</span>\n </label>\n </span>`\n : \"\";\n\n let input: string;\n\n switch (field.type) {\n case \"checkbox\":\n // Nullable boolean → 3-state select (null / true / false)\n if (field.nullable) {\n const sel3 = isNullValue\n ? \"__null__\"\n : defaultStr === \"true\"\n ? \"true\"\n : defaultStr === \"false\"\n ? \"false\"\n : \"__null__\";\n return `\n <div class=\"form-control mb-3 ${indent}\">\n <label for=\"${id}\" class=\"label pb-1\">\n <span class=\"label-text font-medium\">\n ${e(field.label)}\n <span class=\"text-base-content/40 text-xs ml-1\">(nullable)</span>\n </span>\n </label>\n <select id=\"${id}\" name=\"${nameAttr}\" class=\"select select-bordered select-sm w-full\">\n <option value=\"__null__\"${sel3 === \"__null__\" ? \" selected\" : \"\"}>— null —</option>\n <option value=\"true\"${sel3 === \"true\" ? \" selected\" : \"\"}>✓ true</option>\n <option value=\"false\"${sel3 === \"false\" ? \" selected\" : \"\"}>✗ false</option>\n </select>\n </div>`;\n }\n return `\n <div class=\"form-control ${indent}\">\n <label class=\"label cursor-pointer justify-start gap-3\">\n <input type=\"checkbox\" id=\"${id}\" name=\"${nameAttr}\" value=\"true\"${\n defaultStr === \"true\" ? \" checked\" : \"\"\n } class=\"checkbox checkbox-primary checkbox-sm\">\n <span class=\"label-text font-medium\">\n ${e(field.label)}${field.required ? ` <span class=\"text-error\">*</span>` : \"\"}\n </span>\n </label>\n </div>`;\n\n case \"select\":\n input = `<select id=\"${id}\" name=\"${nameAttr}\"${requiredAttr}${isNullValue ? ' disabled style=\"opacity:0.35\"' : \"\"} class=\"select select-bordered select-sm w-full\">\n ${field.required && !field.nullable ? \"\" : `<option value=\"\">— optional —</option>`}\n ${(field.options ?? []).map((o) => `<option value=\"${e(o)}\"${defaultStr === o ? \" selected\" : \"\"}>${e(o)}</option>`).join(\"\\n \")}\n </select>`;\n break;\n\n case \"textarea\":\n if (field.arrayElementType) {\n return renderArrayField(field, depth);\n }\n if (field.nested && field.nested.length > 0) {\n const subFields = field.nested\n .map((f) => renderField(f, depth + 1))\n .join(\"\\n\");\n return `\n <fieldset class=\"fieldset border border-base-300 rounded-box p-3 mb-3 ${indent}\">\n <legend class=\"fieldset-legend text-xs font-semibold text-base-content/60 px-1\">\n ${e(field.label)}${field.required ? ` <span class=\"text-error\">*</span>` : \"\"}\n </legend>\n ${subFields}\n </fieldset>`;\n }\n input = `<textarea id=\"${id}\" name=\"${nameAttr}\"${requiredAttr} rows=\"3\"${isNullValue ? ' disabled style=\"opacity:0.35\"' : \"\"}\n data-json\n class=\"textarea textarea-bordered textarea-sm w-full font-mono text-xs\"\n placeholder=\"${e(field.hint ?? \"JSON\")}\">${e(defaultStr)}</textarea>`;\n break;\n\n default:\n input = `<input type=\"${field.type}\" id=\"${id}\" name=\"${nameAttr}\"${requiredAttr}${isNullValue ? ' disabled style=\"opacity:0.35\"' : \"\"}\n value=\"${e(defaultStr)}\"\n class=\"input input-bordered input-sm w-full\"${\n field.hint === \"email\"\n ? ' autocomplete=\"email\"'\n : field.hint === \"url\"\n ? ' autocomplete=\"url\"'\n : \"\"\n }>`;\n }\n\n return `\n <div class=\"form-control mb-3 ${indent}\">\n <label for=\"${id}\" class=\"label pb-1\">\n <span class=\"label-text font-medium\">\n ${e(field.label)}${field.required ? ` <span class=\"text-error\">*</span>` : \"\"}\n ${field.hint ? `<span class=\"text-base-content/40 text-xs ml-1\">(${e(field.hint)})</span>` : \"\"}\n </span>\n </label>\n <div class=\"flex items-center gap-2\">\n <div class=\"flex-1 min-w-0\">${input}</div>\n ${nullToggle}\n </div>\n </div>`;\n}\n\n/** Minimal HTML escape */\nfunction e(s: string): string {\n return s\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\n// ---------------------------------------------------------------------------\n// Array field rendering\n// ---------------------------------------------------------------------------\n\nfunction renderArrayField(field: FieldDescriptor, depth: number): string {\n const indent = depth > 0 ? `ml-${depth * 4}` : \"\";\n const id = `field_${field.name.replace(/\\./g, \"__\")}`;\n const isNullValue = field.defaultValue === \"__null__\";\n const isObject = field.arrayElementType === \"object\";\n\n // Parse existing value (JSON string → array)\n let items: unknown[] = [];\n if (\n field.defaultValue != null &&\n field.defaultValue !== \"\" &&\n field.defaultValue !== \"__null__\"\n ) {\n try {\n items = JSON.parse(String(field.defaultValue));\n } catch {\n /* ignore */\n }\n }\n if (!Array.isArray(items)) items = [];\n\n const itemsHtml = isObject\n ? items\n .map((item) =>\n renderObjectItem(field, (item as Record<string, unknown>) ?? {}),\n )\n .join(\"\\n\")\n : items.map((item) => renderPrimitiveItem(field, item)).join(\"\\n\");\n\n const templateHtml = isObject\n ? renderObjectItem(field, {})\n : renderPrimitiveItem(field, \"\");\n\n // Null toggle for nullable array fields\n const nullToggle =\n field.nullable\n ? `<span class=\"flex items-center gap-1 mt-2\">\n <input type=\"hidden\" id=\"${id}__isnull\" name=\"${e(field.name)}__isnull\" value=\"${isNullValue ? \"1\" : \"\"}\">\n <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\">\n <input type=\"checkbox\" class=\"checkbox checkbox-xs\" ${isNullValue ? \"checked\" : \"\"}\n onchange=\"(function(cb){\n var fs = cb.closest('[data-frs-array]');\n var h = document.getElementById('${id}__isnull');\n var hidden = document.getElementById('${id}');\n if (cb.checked) { fs.querySelector('[data-frs-array-items]').style.opacity='0.35'; h.value='1'; hidden.disabled=true; }\n else { fs.querySelector('[data-frs-array-items]').style.opacity=''; h.value=''; hidden.disabled=false; }\n })(this)\">\n <span>null</span>\n </label>\n </span>`\n : \"\";\n\n return `\n <fieldset class=\"fieldset border border-base-300 rounded-box p-3 mb-3 ${indent}\"\n data-frs-array=\"${e(field.name)}\" data-frs-array-type=\"${e(field.arrayElementType ?? \"text\")}\">\n <legend class=\"fieldset-legend text-xs font-semibold text-base-content/60 px-1\">\n ${e(field.label)}${field.required ? ` <span class=\"text-error\">*</span>` : \"\"}\n </legend>\n <input type=\"hidden\" id=\"${id}\" name=\"${e(field.name)}\" value=\"${e(JSON.stringify(items))}\"${isNullValue ? \" disabled\" : \"\"}>\n <div data-frs-array-items${isNullValue ? ' style=\"opacity:0.35\"' : \"\"}>\n ${itemsHtml}\n </div>\n <template data-frs-array-tpl>${templateHtml}</template>\n <button type=\"button\" class=\"btn btn-xs btn-outline mt-1\" data-frs-array-add>+ Add</button>\n ${nullToggle}\n </fieldset>`;\n}\n\nfunction renderPrimitiveItem(\n field: FieldDescriptor,\n value: unknown,\n): string {\n const strVal = value != null ? String(value) : \"\";\n let inputHtml: string;\n\n switch (field.arrayElementType) {\n case \"select\":\n inputHtml = `<select data-frs-val class=\"select select-bordered select-sm flex-1\">\n <option value=\"\">—</option>\n ${(field.arrayElementOptions ?? []).map((o) => `<option value=\"${e(o)}\"${strVal === o ? \" selected\" : \"\"}>${e(o)}</option>`).join(\"\")}\n </select>`;\n break;\n case \"checkbox\":\n inputHtml = `<label class=\"flex items-center gap-2 flex-1 cursor-pointer\">\n <input type=\"checkbox\" data-frs-val class=\"checkbox checkbox-sm checkbox-primary\"${strVal === \"true\" ? \" checked\" : \"\"}>\n <span class=\"text-sm\">true</span>\n </label>`;\n break;\n case \"number\":\n inputHtml = `<input type=\"number\" data-frs-val value=\"${e(strVal)}\" class=\"input input-bordered input-sm flex-1\">`;\n break;\n case \"datetime-local\":\n inputHtml = `<input type=\"datetime-local\" data-frs-val value=\"${e(strVal)}\" class=\"input input-bordered input-sm flex-1\">`;\n break;\n default:\n inputHtml = `<input type=\"text\" data-frs-val value=\"${e(strVal)}\" class=\"input input-bordered input-sm flex-1\">`;\n }\n\n return `<div class=\"flex items-center gap-2 mb-2\" data-frs-array-item>\n ${inputHtml}\n <button type=\"button\" class=\"btn btn-xs btn-ghost text-error\" data-frs-array-rm>&times;</button>\n </div>`;\n}\n\nfunction renderObjectItem(\n field: FieldDescriptor,\n obj: Record<string, unknown>,\n): string {\n const elFields = field.arrayElementFields ?? [];\n\n const fieldsHtml = elFields\n .map((f) => {\n const val = obj[f.name];\n const strVal =\n val == null\n ? \"\"\n : typeof val === \"object\"\n ? JSON.stringify(val)\n : String(val);\n\n switch (f.type) {\n case \"checkbox\":\n return `<div class=\"form-control mb-2\">\n <label class=\"label cursor-pointer justify-start gap-3\">\n <input type=\"checkbox\" data-frs-key=\"${e(f.name)}\" class=\"checkbox checkbox-sm checkbox-primary\"${strVal === \"true\" ? \" checked\" : \"\"}>\n <span class=\"label-text text-sm\">${e(f.label)}</span>\n </label>\n </div>`;\n case \"select\":\n return `<div class=\"form-control mb-2\">\n <label class=\"label pb-1\"><span class=\"label-text text-sm\">${e(f.label)}</span></label>\n <select data-frs-key=\"${e(f.name)}\" class=\"select select-bordered select-sm w-full\">\n ${f.required ? \"\" : `<option value=\"\">—</option>`}\n ${(f.options ?? []).map((o) => `<option value=\"${e(o)}\"${strVal === o ? \" selected\" : \"\"}>${e(o)}</option>`).join(\"\")}\n </select>\n </div>`;\n case \"number\":\n return `<div class=\"form-control mb-2\">\n <label class=\"label pb-1\"><span class=\"label-text text-sm\">${e(f.label)}</span></label>\n <input type=\"number\" data-frs-key=\"${e(f.name)}\" value=\"${e(strVal)}\" class=\"input input-bordered input-sm w-full\">\n </div>`;\n case \"datetime-local\":\n return `<div class=\"form-control mb-2\">\n <label class=\"label pb-1\"><span class=\"label-text text-sm\">${e(f.label)}</span></label>\n <input type=\"datetime-local\" data-frs-key=\"${e(f.name)}\" value=\"${e(strVal)}\" class=\"input input-bordered input-sm w-full\">\n </div>`;\n case \"textarea\":\n return `<div class=\"form-control mb-2\">\n <label class=\"label pb-1\"><span class=\"label-text text-sm\">${e(f.label)}</span></label>\n <textarea data-frs-key=\"${e(f.name)}\" rows=\"2\" class=\"textarea textarea-bordered textarea-sm w-full font-mono text-xs\" placeholder=\"JSON\">${e(strVal)}</textarea>\n </div>`;\n default:\n return `<div class=\"form-control mb-2\">\n <label class=\"label pb-1\"><span class=\"label-text text-sm\">${e(f.label)}</span></label>\n <input type=\"text\" data-frs-key=\"${e(f.name)}\" value=\"${e(strVal)}\" class=\"input input-bordered input-sm w-full\">\n </div>`;\n }\n })\n .join(\"\\n\");\n\n return `<div class=\"border border-base-200 rounded p-3 mb-2\" data-frs-array-item>\n <div class=\"flex justify-end mb-1\">\n <button type=\"button\" class=\"btn btn-xs btn-ghost text-error\" data-frs-array-rm>&times;</button>\n </div>\n ${fieldsHtml}\n </div>`;\n}\n\n// ---------------------------------------------------------------------------\n// Full form render\n// ---------------------------------------------------------------------------\n\nexport function renderForm(\n fields: FieldDescriptor[],\n action: string,\n method: \"GET\" | \"POST\",\n submitLabel = \"Save\",\n): string {\n const fieldsHtml = fields.map((f) => renderField(f)).join(\"\\n\");\n return `\n <form action=\"${e(action)}\" method=\"${method}\" novalidate data-frs-form>\n ${fieldsHtml}\n <div class=\"flex gap-2 mt-4 pt-4 border-t border-base-200\">\n <button type=\"submit\" class=\"btn btn-primary btn-sm\">${e(submitLabel)}</button>\n <button type=\"button\" class=\"btn btn-ghost btn-sm\" onclick=\"history.back()\">Cancel</button>\n </div>\n </form>`;\n}\n","function CellDate({ val }: { val: Date }) {\n return (\n <span class=\"text-sm text-base-content/80 font-mono tabular-nums whitespace-nowrap\">\n {val.toLocaleString()}\n </span>\n );\n}\n\nexport function CellValue({ val }: { val: unknown }) {\n if (val === null || val === undefined) {\n return <span class=\"opacity-30 italic text-xs\">—</span>;\n }\n\n if (typeof val === \"boolean\") {\n return val ? (\n <span class=\"badge badge-success badge-sm\">true</span>\n ) : (\n <span class=\"badge badge-error badge-sm\">false</span>\n );\n }\n\n if (val instanceof Date) {\n return <CellDate val={val} />;\n }\n\n // Firestore Timestamp (.toDate())\n if (\n typeof val === \"object\" &&\n val !== null &&\n typeof (val as any).toDate === \"function\"\n ) {\n return <CellDate val={(val as any).toDate() as Date} />;\n }\n\n if (typeof val === \"number\") {\n return <span class=\"text-sm font-mono tabular-nums\">{String(val)}</span>;\n }\n\n if (Array.isArray(val)) {\n if (val.length === 0)\n return <span class=\"text-xs text-base-content/30\">{\"[]\"}</span>;\n return (\n <ul class=\"list-none p-0 m-0 space-y-0.5 text-xs\">\n {val.slice(0, 8).map((item, i) => (\n <li key={i} class=\"break-all\">\n {typeof item === \"object\" ? JSON.stringify(item) : String(item)}\n </li>\n ))}\n {val.length > 8 && (\n <li class=\"text-base-content/40 italic\">\n +{val.length - 8} more…\n </li>\n )}\n </ul>\n );\n }\n\n if (typeof val === \"object\" && val !== null) {\n const entries = Object.entries(val as Record<string, unknown>);\n if (entries.length === 0)\n return <span class=\"text-xs text-base-content/30\">{\"{}\"}</span>;\n return (\n <dl class=\"grid grid-cols-[auto_1fr] gap-x-2 gap-y-0.5 text-xs m-0\">\n {entries.slice(0, 8).map(([k, v]) => (\n <>\n <dt class=\"text-base-content/50 font-semibold whitespace-nowrap\">\n {k}\n </dt>\n <dd class=\"break-all\">{String(v ?? \"\")}</dd>\n </>\n ))}\n {entries.length > 8 && (\n <dt class=\"col-span-2 text-base-content/40 italic\">\n +{entries.length - 8} more…\n </dt>\n )}\n </dl>\n );\n }\n\n const str = String(val);\n return <span class=\"text-sm break-all\">{str}</span>;\n}\n","// ── Form validation + array serialization ───────────────────────────────────\ndocument.addEventListener(\"submit\", function (e) {\n var form = e.target;\n if (!form.hasAttribute(\"data-frs-form\")) return;\n\n // 1. Validate JSON textareas\n var valid = true;\n form.querySelectorAll(\"textarea[data-json]\").forEach(function (ta) {\n var v = ta.value.trim();\n if (!v) return;\n try {\n JSON.parse(v);\n } catch (err) {\n valid = false;\n e.preventDefault();\n alert('Invalid JSON in field \"' + ta.name + '\":\\n' + err.message);\n }\n });\n if (!valid) return;\n\n // 2. Serialize array fields into hidden inputs\n form.querySelectorAll(\"[data-frs-array]\").forEach(function (fieldset) {\n var hidden = fieldset.querySelector(\"input[type=hidden][name]\");\n if (!hidden || hidden.disabled) return;\n\n var type = fieldset.getAttribute(\"data-frs-array-type\");\n var items = fieldset.querySelectorAll(\"[data-frs-array-item]\");\n var arr = [];\n\n if (type === \"object\") {\n items.forEach(function (item) {\n var obj = {};\n item.querySelectorAll(\"[data-frs-key]\").forEach(function (inp) {\n var key = inp.getAttribute(\"data-frs-key\");\n if (inp.type === \"checkbox\") {\n obj[key] = inp.checked;\n } else if (inp.type === \"number\") {\n obj[key] = inp.value === \"\" ? null : Number(inp.value);\n } else if (inp.tagName === \"TEXTAREA\") {\n var v = inp.value.trim();\n if (v) {\n try {\n obj[key] = JSON.parse(v);\n } catch (_) {\n obj[key] = v;\n }\n } else {\n obj[key] = null;\n }\n } else {\n obj[key] = inp.value;\n }\n });\n arr.push(obj);\n });\n } else {\n items.forEach(function (item) {\n var inp = item.querySelector(\"[data-frs-val]\");\n if (!inp) return;\n if (type === \"checkbox\") {\n arr.push(inp.checked);\n } else if (type === \"number\") {\n if (inp.value !== \"\") arr.push(Number(inp.value));\n } else {\n if (inp.value !== \"\") arr.push(inp.value);\n }\n });\n }\n\n hidden.value = JSON.stringify(arr);\n });\n});\n\n// ── Array add / remove buttons ──────────────────────────────────────────────\ndocument.addEventListener(\"click\", function (e) {\n // Add item\n var addBtn = e.target.closest(\"[data-frs-array-add]\");\n if (addBtn) {\n var fieldset = addBtn.closest(\"[data-frs-array]\");\n if (!fieldset) return;\n var tpl = fieldset.querySelector(\"template[data-frs-array-tpl]\");\n var container = fieldset.querySelector(\"[data-frs-array-items]\");\n if (!tpl || !container) return;\n var clone = tpl.content.cloneNode(true);\n container.appendChild(clone);\n var last = container.lastElementChild;\n if (last) {\n var firstInp = last.querySelector(\"input,select,textarea\");\n if (firstInp) firstInp.focus();\n }\n return;\n }\n\n // Remove item\n var rmBtn = e.target.closest(\"[data-frs-array-rm]\");\n if (rmBtn) {\n var item = rmBtn.closest(\"[data-frs-array-item]\");\n if (item) item.remove();\n }\n});\n\n// ── Table enhancements ──────────────────────────────────────────────────────\ndocument.addEventListener(\"DOMContentLoaded\", function () {\n document.querySelectorAll(\"table[data-frs-table]\").forEach(initTable);\n});\n\nfunction initTable(table) {\n tagOriginalIndices(table);\n applySavedColumnOrder(table);\n initColumnResize(table);\n initColumnVisibility(table);\n initColumnReorder(table);\n}\n\n// ── Tag original column indices ─────────────────────────────────────────────\nfunction tagOriginalIndices(table) {\n var ths = Array.from(table.querySelectorAll(\"thead th\"));\n var dataCount = countDataColumns(table, ths);\n for (var i = 0; i < dataCount; i++) {\n ths[i].setAttribute(\"data-orig-col\", String(i));\n }\n table.querySelectorAll(\"tbody tr\").forEach(function (row) {\n var tds = Array.from(row.querySelectorAll(\"td\"));\n for (var j = 0; j < dataCount && j < tds.length; j++) {\n tds[j].setAttribute(\"data-orig-col\", String(j));\n }\n });\n}\n\nfunction countDataColumns(table, ths) {\n var explicit = table.getAttribute(\"data-frs-colcount\");\n if (explicit) return parseInt(explicit, 10);\n var count = 0;\n for (var i = 0; i < ths.length; i++) {\n if (ths[i].querySelector(\"a[href]\")) count++;\n else break;\n }\n return count || Math.max(0, ths.length - 1);\n}\n\n// ── Apply saved column order ────────────────────────────────────────────────\nfunction applySavedColumnOrder(table) {\n var repo = table.getAttribute(\"data-frs-repo\") || \"default\";\n var saved;\n try {\n saved = JSON.parse(localStorage.getItem(\"frs_colorder_\" + repo));\n } catch (_) {\n return;\n }\n if (!saved || !Array.isArray(saved) || saved.length === 0) return;\n reorderColumns(table, saved);\n}\n\n// ── Reorder columns by orig-index array ─────────────────────────────────────\nfunction reorderColumns(table, order) {\n var headRow = table.querySelector(\"thead tr\");\n if (!headRow) return;\n reorderRow(headRow, order);\n table.querySelectorAll(\"tbody tr\").forEach(function (row) {\n reorderRow(row, order);\n });\n}\n\nfunction reorderRow(row, order) {\n var cells = Array.from(row.children);\n var dataCells = cells.filter(function (c) {\n return c.hasAttribute(\"data-orig-col\");\n });\n var tailCells = cells.filter(function (c) {\n return !c.hasAttribute(\"data-orig-col\");\n });\n var cellMap = {};\n dataCells.forEach(function (c) {\n cellMap[c.getAttribute(\"data-orig-col\")] = c;\n });\n while (row.firstChild) row.removeChild(row.firstChild);\n order.forEach(function (origIdx) {\n if (cellMap[origIdx]) row.appendChild(cellMap[origIdx]);\n });\n dataCells.forEach(function (c) {\n if (!row.contains(c)) row.appendChild(c);\n });\n tailCells.forEach(function (c) {\n row.appendChild(c);\n });\n}\n\n// ── Column resize ───────────────────────────────────────────────────────────\nfunction initColumnResize(table) {\n var ths = Array.from(table.querySelectorAll(\"thead th\"));\n ths.forEach(function (th, i) {\n if (i === ths.length - 1) return;\n th.style.position = \"relative\";\n var handle = document.createElement(\"div\");\n handle.style.cssText =\n \"position:absolute;right:0;top:0;bottom:0;width:5px;cursor:col-resize;z-index:10;\";\n handle.addEventListener(\"mousedown\", function (e) {\n e.preventDefault();\n e.stopPropagation();\n var startX = e.clientX,\n startW = th.offsetWidth;\n var line = document.createElement(\"div\");\n line.style.cssText =\n \"position:fixed;top:0;bottom:0;width:2px;background:oklch(0.585 0.233 277.117);opacity:0.5;pointer-events:none;z-index:9999;\";\n line.style.left = e.clientX + \"px\";\n document.body.appendChild(line);\n function onMove(ev) {\n var newW = Math.max(40, startW + ev.clientX - startX);\n th.style.width = newW + \"px\";\n th.style.minWidth = newW + \"px\";\n line.style.left = ev.clientX + \"px\";\n }\n function onUp() {\n document.body.removeChild(line);\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n }\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n });\n th.appendChild(handle);\n });\n}\n\n// ── Column visibility (Columns dropdown with checkboxes) ────────────────────\nfunction initColumnVisibility(table) {\n var dataThs = Array.from(table.querySelectorAll(\"thead th[data-orig-col]\"));\n if (dataThs.length === 0) return;\n\n var wrap = table.closest(\"[data-frs-table-wrap]\");\n var toolbar = wrap && wrap.previousElementSibling;\n if (!toolbar) return;\n\n var repo = table.getAttribute(\"data-frs-repo\") || \"default\";\n var storageKey = \"frs_cols_\" + repo;\n var savedState = {};\n try {\n savedState = JSON.parse(localStorage.getItem(storageKey) || \"{}\");\n } catch (_) {}\n\n function saveState(origIdx, visible) {\n savedState[origIdx] = visible;\n try {\n localStorage.setItem(storageKey, JSON.stringify(savedState));\n } catch (_) {}\n }\n\n function setColVisible(origIdx, visible) {\n var th = table.querySelector('thead th[data-orig-col=\"' + origIdx + '\"]');\n if (th) th.style.display = visible ? \"\" : \"none\";\n table\n .querySelectorAll('tbody td[data-orig-col=\"' + origIdx + '\"]')\n .forEach(function (td) {\n td.style.display = visible ? \"\" : \"none\";\n });\n }\n\n var cols = dataThs.map(function (th) {\n var origIdx = parseInt(th.getAttribute(\"data-orig-col\"), 10);\n return {\n origIndex: origIdx,\n label: th.textContent.replace(/\\s+/g, \" \").trim(),\n };\n });\n\n // Build dropdown\n var dropdown = document.createElement(\"div\");\n dropdown.className = \"dropdown dropdown-end\";\n\n var btn = document.createElement(\"button\");\n btn.type = \"button\";\n btn.tabIndex = 0;\n btn.className = \"btn btn-sm btn-outline gap-1\";\n btn.innerHTML =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"size-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\">' +\n '<path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 4v16M15 4v16M4 9h16M4 15h16\"/>' +\n \"</svg> Columns\";\n dropdown.appendChild(btn);\n\n var menu = document.createElement(\"ul\");\n menu.tabIndex = 0;\n menu.className =\n \"dropdown-content menu bg-base-100 rounded-box z-50 p-2 shadow-lg border border-base-300 w-56 max-h-80 overflow-y-auto flex-nowrap\";\n\n cols.forEach(function (col) {\n var li = document.createElement(\"li\");\n var label = document.createElement(\"label\");\n label.className =\n \"flex items-center gap-2 cursor-pointer px-2 py-1.5 rounded hover:bg-base-200\";\n\n var cb = document.createElement(\"input\");\n cb.type = \"checkbox\";\n cb.className = \"checkbox checkbox-xs checkbox-primary\";\n var isVisible = savedState[col.origIndex] !== false;\n cb.checked = isVisible;\n\n var span = document.createElement(\"span\");\n span.className = \"text-sm select-none\";\n span.textContent = col.label || \"Column \" + (col.origIndex + 1);\n\n label.appendChild(cb);\n label.appendChild(span);\n li.appendChild(label);\n\n if (!isVisible) setColVisible(col.origIndex, false);\n\n cb.addEventListener(\"change\", function (e) {\n var visible = e.target.checked;\n setColVisible(col.origIndex, visible);\n saveState(col.origIndex, visible);\n });\n\n menu.appendChild(li);\n });\n\n dropdown.appendChild(menu);\n toolbar.appendChild(dropdown);\n}\n\n// ── Column reorder (drag grip handles on headers) ───────────────────────────\nfunction initColumnReorder(table) {\n var repo = table.getAttribute(\"data-frs-repo\") || \"default\";\n var orderKey = \"frs_colorder_\" + repo;\n var dragSrcTh = null;\n var allDataThs = Array.from(\n table.querySelectorAll(\"thead th[data-orig-col]\"),\n );\n if (allDataThs.length < 2) return;\n\n allDataThs.forEach(function (th) {\n // Prepend a drag grip\n var grip = document.createElement(\"span\");\n grip.draggable = true;\n grip.textContent = \"\\u2807\";\n grip.style.cssText =\n \"cursor:grab;opacity:0.18;margin-right:4px;font-size:14px;vertical-align:middle;user-select:none;display:inline-block;\";\n grip.addEventListener(\"mouseenter\", function () {\n grip.style.opacity = \"0.5\";\n });\n grip.addEventListener(\"mouseleave\", function () {\n grip.style.opacity = \"0.18\";\n });\n th.insertBefore(grip, th.firstChild);\n\n // Drag starts from the grip only\n grip.addEventListener(\"dragstart\", function (e) {\n dragSrcTh = th;\n th.style.opacity = \"0.35\";\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", \"col\");\n try {\n e.dataTransfer.setDragImage(th, 20, 16);\n } catch (_) {}\n });\n\n grip.addEventListener(\"dragend\", function () {\n if (dragSrcTh) dragSrcTh.style.opacity = \"\";\n dragSrcTh = null;\n allDataThs.forEach(function (t) {\n t.style.boxShadow = \"\";\n });\n });\n\n // Drop target is the full <th>\n th.addEventListener(\"dragover\", function (e) {\n if (!dragSrcTh || dragSrcTh === th) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n allDataThs.forEach(function (t) {\n t.style.boxShadow = \"\";\n });\n var rect = th.getBoundingClientRect();\n var midX = rect.left + rect.width / 2;\n if (e.clientX < midX) {\n th.style.boxShadow = \"inset 3px 0 0 oklch(0.585 0.233 277.117)\";\n } else {\n th.style.boxShadow = \"inset -3px 0 0 oklch(0.585 0.233 277.117)\";\n }\n });\n\n th.addEventListener(\"dragleave\", function () {\n th.style.boxShadow = \"\";\n });\n\n th.addEventListener(\"drop\", function (e) {\n e.preventDefault();\n if (!dragSrcTh || dragSrcTh === th) return;\n allDataThs.forEach(function (t) {\n t.style.boxShadow = \"\";\n });\n\n var headRow = th.parentNode;\n var rect = th.getBoundingClientRect();\n var midX = rect.left + rect.width / 2;\n if (e.clientX < midX) {\n headRow.insertBefore(dragSrcTh, th);\n } else {\n headRow.insertBefore(dragSrcTh, th.nextElementSibling);\n }\n\n // Read new order from the reordered thead\n var newOrder = Array.from(\n table.querySelectorAll(\"thead th[data-orig-col]\"),\n ).map(function (t) {\n return parseInt(t.getAttribute(\"data-orig-col\"), 10);\n });\n\n // Apply the same order to all tbody rows\n table.querySelectorAll(\"tbody tr\").forEach(function (row) {\n reorderRow(row, newOrder);\n });\n\n // Persist\n try {\n localStorage.setItem(orderKey, JSON.stringify(newOrder));\n } catch (_) {}\n });\n });\n}\n","import JS from \"./client-script.raw.js\";\n\nexport function ClientScript() {\n // dangerouslySetInnerHTML is required here: JSX would escape < > & inside\n // a <script> text child, breaking the JavaScript at runtime.\n return <script dangerouslySetInnerHTML={{ __html: JS }} />;\n}\n","import type { Child, FC, PropsWithChildren } from \"hono/jsx\";\nimport { renderToString } from \"hono/jsx/dom/server\";\nimport { ClientScript } from \"./client-script\";\nimport type { PageOptions } from \"./types\";\n\n/** Render a JSX element to a complete HTML string (includes <!DOCTYPE html>) */\nexport function renderHtml(element: Child): string {\n return \"<!DOCTYPE html>\" + renderToString(element);\n}\n\nexport const PageShell: FC<PropsWithChildren<{ opts: PageOptions }>> = ({\n opts,\n children,\n}) => {\n const { title, breadcrumb, flash, basePath = \"/\" } = opts;\n\n return (\n <html lang=\"en\" data-theme=\"corporate\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>{title} — FRS Admin</title>\n <link\n href=\"https://cdn.jsdelivr.net/npm/daisyui@5/themes.css\"\n rel=\"stylesheet\"\n type=\"text/css\"\n />\n <link\n href=\"https://cdn.jsdelivr.net/npm/daisyui@5/daisyui.css\"\n rel=\"stylesheet\"\n type=\"text/css\"\n />\n <script src=\"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4\" />\n </head>\n <body class=\"bg-base-200/50 min-h-screen flex flex-col\">\n {/* Navbar */}\n <div class=\"navbar bg-neutral text-neutral-content shadow-sm sticky top-0 z-50 px-6\">\n <div class=\"flex-1\">\n <a\n href={basePath}\n class=\"font-bold text-lg tracking-tight hover:opacity-80 transition-opacity\"\n >\n FRS Admin\n </a>\n </div>\n </div>\n\n <main class=\"px-6 py-8 w-full flex-1\">\n {/* Breadcrumbs */}\n {breadcrumb && breadcrumb.length > 0 && (\n <div class=\"text-sm breadcrumbs mb-4\">\n <ul>\n {breadcrumb.map((c, i) =>\n c.href ? (\n <li key={i}>\n <a href={c.href}>{c.label}</a>\n </li>\n ) : (\n <li key={i} class=\"text-base-content/60\">\n {c.label}\n </li>\n ),\n )}\n </ul>\n </div>\n )}\n\n <h1 class=\"text-2xl font-bold mb-6\">{title}</h1>\n\n {/* Flash message */}\n {flash && (\n <div\n role=\"alert\"\n class={`alert ${flash.type === \"success\" ? \"alert-success\" : \"alert-error\"} mb-6`}\n >\n <span>{flash.message}</span>\n </div>\n )}\n\n {children}\n </main>\n\n <ClientScript />\n </body>\n </html>\n );\n};\n\n/** Wrap a raw HTML string in the page shell (backward compat). */\nexport function renderPageJsx(content: string, opts: PageOptions): string {\n return renderHtml(\n <PageShell opts={opts}>\n <div dangerouslySetInnerHTML={{ __html: content }} />\n </PageShell>,\n );\n}\n","import { PageShell, renderHtml } from \"./shell\";\n\nexport function renderDashboardJsx(\n repos: { name: string; path: string }[],\n basePath: string,\n): string {\n return renderHtml(\n <PageShell opts={{ title: \"Repositories\", basePath }}>\n {repos.length === 0 ? (\n <div class=\"text-center py-20 text-base-content/50\">\n <p class=\"text-lg font-medium mb-1\">No repositories configured</p>\n <p class=\"text-sm\">\n Add a repository to your FRS config to get started.\n </p>\n </div>\n ) : (\n <div class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4\">\n {repos.map((r) => (\n <a\n key={r.name}\n href={`${basePath}/${r.name}`}\n class=\"card bg-base-100 border border-base-300 hover:shadow-md no-underline transition-shadow\"\n >\n <div class=\"card-body p-5\">\n <h2 class=\"card-title text-sm font-semibold\">{r.name}</h2>\n <p class=\"text-xs text-base-content/50 font-mono\">{r.path}</p>\n </div>\n </a>\n ))}\n </div>\n )}\n </PageShell>,\n );\n}\n","import type { ColumnMeta, FilterState, WhereOp } from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Operator definitions per Zod type\n// ---------------------------------------------------------------------------\n\ntype OpDef = { value: WhereOp; label: string };\n\nconst OPS_TEXT: OpDef[] = [\n { value: \"==\", label: \"=\" },\n { value: \"!=\", label: \"≠\" },\n];\nconst OPS_NUMERIC: OpDef[] = [\n { value: \"==\", label: \"=\" },\n { value: \"!=\", label: \"≠\" },\n { value: \"<\", label: \"<\" },\n { value: \"<=\", label: \"≤\" },\n { value: \">\", label: \">\" },\n { value: \">=\", label: \"≥\" },\n];\nconst OPS_ARRAY: OpDef[] = [\n { value: \"array-contains\", label: \"contains\" },\n { value: \"array-contains-any\", label: \"contains any\" },\n];\n\nfunction opsForType(zodType: string): OpDef[] {\n switch (zodType) {\n case \"ZodNumber\":\n case \"ZodBigInt\":\n case \"ZodDate\":\n return OPS_NUMERIC;\n case \"ZodBoolean\":\n return OPS_TEXT;\n case \"ZodArray\":\n return OPS_ARRAY;\n default:\n return OPS_TEXT;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Value input per type\n// ---------------------------------------------------------------------------\n\nfunction FilterValueInput({\n col,\n active,\n}: {\n col: ColumnMeta;\n active?: FilterState;\n}) {\n const val = active?.value ?? \"\";\n\n if (col.zodType === \"ZodBoolean\") {\n return (\n <select\n name={`fv_${col.name}`}\n class=\"select select-sm select-bordered w-full\"\n >\n <option value=\"\" selected={val === \"\"}>\n —\n </option>\n <option value=\"true\" selected={val === \"true\"}>\n true\n </option>\n <option value=\"false\" selected={val === \"false\"}>\n false\n </option>\n </select>\n );\n }\n if (col.zodType === \"ZodArray\") {\n const isAny = active?.op === \"array-contains-any\";\n return (\n <input\n type=\"text\"\n name={`fv_${col.name}`}\n value={val}\n placeholder={isAny ? \"val1, val2, …\" : \"value\"}\n class=\"input input-sm input-bordered w-full\"\n />\n );\n }\n if (col.zodType === \"ZodNumber\" || col.zodType === \"ZodBigInt\") {\n return (\n <input\n type=\"number\"\n name={`fv_${col.name}`}\n value={val}\n placeholder=\"value\"\n class=\"input input-sm input-bordered w-full\"\n />\n );\n }\n if (col.zodType === \"ZodDate\") {\n return (\n <input\n type=\"datetime-local\"\n name={`fv_${col.name}`}\n value={val}\n class=\"input input-sm input-bordered w-full\"\n />\n );\n }\n return (\n <input\n type=\"text\"\n name={`fv_${col.name}`}\n value={val}\n placeholder=\"value\"\n class=\"input input-sm input-bordered w-full\"\n />\n );\n}\n\n// ---------------------------------------------------------------------------\n// FilterBar\n// ---------------------------------------------------------------------------\n\nexport function FilterBar({\n action,\n columnMeta,\n activeFilters,\n}: {\n /** Form action URL (list page URL, without query params) */\n action: string;\n columnMeta: ColumnMeta[];\n activeFilters: FilterState[];\n}) {\n const activeMap = Object.fromEntries(activeFilters.map((f) => [f.field, f]));\n const hasActive = activeFilters.length > 0;\n\n // Columns that can be filtered (exclude pure-object columns)\n const filterable = columnMeta.filter(\n (c) => c.zodType !== \"ZodObject\" && c.zodType !== \"ZodRecord\",\n );\n\n return (\n <details\n class=\"collapse collapse-arrow bg-base-100 border border-base-300 rounded-box mb-6 shadow-sm\"\n open={hasActive ? true : undefined}\n >\n <summary class=\"collapse-title text-sm font-medium py-2 min-h-0\">\n Filters\n {hasActive && (\n <span class=\"badge badge-primary badge-sm ml-2\">\n {activeFilters.length} active\n </span>\n )}\n </summary>\n <div class=\"collapse-content pb-4 pt-2\">\n <form method=\"get\" action={action}>\n <div class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4\">\n {filterable.map((col) => {\n const ops = opsForType(col.zodType);\n const active = activeMap[col.name];\n const currentOp: WhereOp = active?.op ?? ops[0]!.value;\n return (\n <div key={col.name} class=\"flex flex-col gap-1.5\">\n <label class=\"text-xs font-semibold text-base-content/60 uppercase tracking-wide\">\n {col.name}\n </label>\n <div class=\"flex gap-1.5\">\n {ops.length > 1 ? (\n <select\n name={`fo_${col.name}`}\n class=\"select select-sm select-bordered w-20 shrink-0\"\n >\n {ops.map((o) => (\n <option\n key={o.value}\n value={o.value}\n selected={o.value === currentOp}\n >\n {o.label}\n </option>\n ))}\n </select>\n ) : (\n // Single op → hidden input, no select to clutter UI\n <input\n type=\"hidden\"\n name={`fo_${col.name}`}\n value={ops[0]!.value}\n />\n )}\n <FilterValueInput col={col} active={active} />\n </div>\n </div>\n );\n })}\n </div>\n\n <div class=\"flex gap-2 mt-4 pt-3 border-t border-base-200\">\n <button type=\"submit\" class=\"btn btn-sm btn-primary\">\n Apply\n </button>\n {hasActive && (\n <a href={action} class=\"btn btn-sm btn-ghost\">\n Clear\n </a>\n )}\n </div>\n </form>\n </div>\n </details>\n );\n}\n","import { PageShell, renderHtml } from \"./shell\";\nimport type { PageOptions } from \"./types\";\n\nexport function renderFormPageJsx(\n repoName: string,\n formHtml: string,\n mode: \"create\" | \"edit\",\n docId: string | null,\n basePath: string,\n flash?: PageOptions[\"flash\"],\n): string {\n const title =\n mode === \"create\"\n ? `Create ${repoName}`\n : `Edit ${repoName} / ${docId ?? \"\"}`;\n\n const crumbs =\n mode === \"create\"\n ? [\n { label: \"Repositories\", href: basePath },\n { label: repoName, href: `${basePath}/${repoName}` },\n { label: \"New document\" },\n ]\n : [\n { label: \"Repositories\", href: basePath },\n { label: repoName, href: `${basePath}/${repoName}` },\n { label: `Edit ${docId ?? \"\"}` },\n ];\n\n return renderHtml(\n <PageShell opts={{ title, breadcrumb: crumbs, basePath, flash }}>\n <div class=\"card bg-base-100 border border-base-300\">\n <div class=\"card-body p-6\">\n <div dangerouslySetInnerHTML={{ __html: formHtml }} />\n </div>\n </div>\n </PageShell>,\n );\n}\n","import { CellValue } from \"./cell-value\";\nimport { FilterBar } from \"./filter-bar\";\nimport { PageShell, renderHtml } from \"./shell\";\nimport type {\n ColumnMeta,\n FilterState,\n PageOptions,\n RelationalFieldMeta,\n SortState,\n} from \"./types\";\n\n/** Shared helper — gather filter params into URLSearchParams. */\nfunction baseParams(\n filters: FilterState[],\n sort?: SortState,\n pageSize?: number,\n): URLSearchParams {\n const p = new URLSearchParams();\n for (const f of filters) {\n p.set(`fv_${f.field}`, f.value);\n p.set(`fo_${f.field}`, f.op);\n }\n if (sort) {\n p.set(\"ob\", sort.field);\n p.set(\"od\", sort.dir);\n }\n if (pageSize) p.set(\"ps\", String(pageSize));\n return p;\n}\n\n/**\n * Build a query-string for pagination (preserves filters, sort, page-size).\n */\nfunction paginationHref(\n filters: FilterState[],\n cursor: string,\n dir: \"prev\" | \"next\",\n sort?: SortState,\n pageSize?: number,\n): string {\n const p = baseParams(filters, sort, pageSize);\n p.set(\"cursor\", cursor);\n p.set(\"dir\", dir);\n return `?${p.toString()}`;\n}\n\n/**\n * Build a query-string that toggles / cycles the sort on a column.\n * Clears the cursor so the user starts from page 1 of the new order.\n */\nfunction sortHref(\n col: string,\n current: SortState | undefined,\n filters: FilterState[],\n pageSize?: number,\n): string {\n const p = baseParams(filters, undefined, pageSize);\n if (current?.field === col) {\n if (current.dir === \"asc\") {\n p.set(\"ob\", col);\n p.set(\"od\", \"desc\");\n }\n // desc → no ob/od (back to default order)\n } else {\n p.set(\"ob\", col);\n p.set(\"od\", \"asc\");\n }\n return `?${p.toString()}`;\n}\n\n/** Build a query-string that changes page size (clears cursor). */\nfunction pageSizeHref(\n newPs: number,\n filters: FilterState[],\n sort?: SortState,\n): string {\n const p = baseParams(filters, sort, newPs);\n return `?${p.toString()}`;\n}\n\nexport function renderListJsx(\n repoName: string,\n docs: Record<string, unknown>[],\n columns: string[],\n basePath: string,\n pagination: {\n hasPrev: boolean;\n hasNext: boolean;\n prevCursor: string;\n nextCursor: string;\n },\n flash?: PageOptions[\"flash\"],\n columnMeta: ColumnMeta[] = [],\n activeFilters: FilterState[] = [],\n allowDelete = false,\n relationalMeta: RelationalFieldMeta[] = [],\n sortState?: SortState,\n currentPageSize?: number,\n): string {\n const listUrl = `${basePath}/${repoName}`;\n const createUrl = `${listUrl}/create`;\n\n return renderHtml(\n <PageShell\n opts={{\n title: repoName,\n breadcrumb: [\n { label: \"Repositories\", href: basePath },\n { label: repoName },\n ],\n basePath,\n flash,\n }}\n >\n {/* Filter panel */}\n {columnMeta.length > 0 && (\n <FilterBar\n action={listUrl}\n columnMeta={columnMeta}\n activeFilters={activeFilters}\n />\n )}\n\n {/* Toolbar */}\n <div class=\"flex flex-wrap justify-between items-center mb-4 gap-3\">\n <div class=\"flex items-center gap-3\">\n <span class=\"text-sm text-base-content/60\">\n {docs.length} document{docs.length !== 1 && \"s\"}\n </span>\n {/* Rows-per-page */}\n <div class=\"flex items-center gap-1.5 text-sm text-base-content/60\">\n <span>Rows</span>\n <div class=\"join\">\n {[10, 25, 50, 100].map((ps) => (\n <a\n key={ps}\n href={pageSizeHref(ps, activeFilters, sortState)}\n class={`join-item btn btn-xs ${currentPageSize === ps ? \"btn-active btn-primary\" : \"btn-outline\"}`}\n >\n {ps}\n </a>\n ))}\n </div>\n </div>\n </div>\n <a href={createUrl} class=\"btn btn-primary btn-sm\">\n + New\n </a>\n </div>\n\n {/* Table */}\n <div\n class=\"overflow-x-auto rounded-box border border-base-300 bg-base-100\"\n data-frs-table-wrap\n >\n <table\n class=\"table table-sm w-full\"\n data-frs-table\n data-frs-repo={repoName}\n data-frs-colcount={columns.length}\n >\n <thead>\n <tr class=\"bg-base-200/50\">\n {[...columns].map((c, i) => {\n const isSorted = sortState?.field === c;\n const arrow = isSorted\n ? sortState!.dir === \"asc\"\n ? \" ▲\"\n : \" ▼\"\n : \"\";\n return (\n <th\n key={i}\n class=\"text-xs font-semibold text-base-content/60 uppercase tracking-wide\"\n >\n <a\n href={sortHref(\n c,\n sortState,\n activeFilters,\n currentPageSize,\n )}\n class={`hover:text-base-content inline-flex items-center gap-0.5${isSorted ? \" text-primary font-bold\" : \"\"}`}\n >\n {c}\n {arrow}\n </a>\n </th>\n );\n })}\n {relationalMeta.map((m, i) => (\n <th\n key={`rel-${i}`}\n class=\"text-xs font-semibold text-base-content/60 uppercase tracking-wide\"\n >\n {m.column}\n </th>\n ))}\n <th class=\"text-xs font-semibold text-base-content/60 uppercase tracking-wide text-right\">\n Actions\n </th>\n </tr>\n </thead>\n <tbody>\n {docs.length === 0 ? (\n <tr>\n <td\n colspan={columns.length + relationalMeta.length + 1}\n class=\"text-center py-16 text-base-content/40\"\n >\n No documents found\n </td>\n </tr>\n ) : (\n docs.map((doc, rowIdx) => {\n const id = String(doc[\"docId\"] ?? doc[\"id\"] ?? \"\");\n const editUrl = `${basePath}/${repoName}/${encodeURIComponent(id)}/edit`;\n const deleteUrl = `${basePath}/${repoName}/${encodeURIComponent(id)}/delete`;\n return (\n <tr key={rowIdx} class=\"hover\">\n {columns.map((c, ci) => (\n <td key={ci} class=\"align-top py-2\">\n <CellValue val={doc[c]} />\n </td>\n ))}\n {relationalMeta.map((m, mi) => {\n const rawVal = doc[m.key];\n if (rawVal == null || rawVal === \"\") {\n return <td key={`rel-${mi}`} class=\"py-2\" />;\n }\n const href = `${basePath}/${m.targetRepo}?fv_${m.targetKey}=${encodeURIComponent(String(rawVal))}`;\n return (\n <td key={`rel-${mi}`} class=\"align-middle py-2\">\n <a\n href={href}\n class=\"btn btn-xs btn-ghost btn-outline\"\n >\n {m.column}\n </a>\n </td>\n );\n })}\n <td class=\"align-middle text-right whitespace-nowrap py-2\">\n <div class=\"flex gap-1 justify-end\">\n <a\n href={editUrl}\n class=\"btn btn-xs btn-outline\"\n >\n Edit\n </a>\n {allowDelete && (\n <form\n method=\"post\"\n action={deleteUrl}\n onsubmit=\"return confirm('Delete this document?')\"\n >\n <button\n type=\"submit\"\n class=\"btn btn-xs btn-error btn-outline\"\n >\n Delete\n </button>\n </form>\n )}\n </div>\n </td>\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n\n {/* Pagination */}\n {(pagination.hasPrev || pagination.hasNext) && (\n <div class=\"flex justify-center items-center mt-6 gap-2\">\n {pagination.hasPrev ? (\n <a\n href={paginationHref(\n activeFilters,\n pagination.prevCursor,\n \"prev\",\n sortState,\n currentPageSize,\n )}\n class=\"btn btn-sm btn-outline\"\n >\n ← Previous\n </a>\n ) : (\n <button class=\"btn btn-sm btn-outline\" disabled>\n ← Previous\n </button>\n )}\n {pagination.hasNext ? (\n <a\n href={paginationHref(\n activeFilters,\n pagination.nextCursor,\n \"next\",\n sortState,\n currentPageSize,\n )}\n class=\"btn btn-sm btn-outline\"\n >\n Next →\n </a>\n ) : (\n <button class=\"btn btn-sm btn-outline\" disabled>\n Next →\n </button>\n )}\n </div>\n )}\n </PageShell>,\n );\n}\n","/**\n * Admin UI renderer — HTML generation functions for the admin interface.\n * All HTML generation is done via JSX in components.tsx.\n * This file preserves the original public API for backward compatibility.\n *\n * @example\n * ```typescript\n * import {\n * renderPage,\n * renderDashboard,\n * renderList,\n * renderFormPage,\n * ClientScript,\n * CSS,\n * } from \"@lpdjs/firestore-repo-service/servers/admin\";\n *\n * // Render a complete page with shell\n * const html = renderPage(\"<h1>Content</h1>\", {\n * title: \"My Admin\",\n * basePath: \"/admin\",\n * });\n *\n * // Render dashboard listing all repositories\n * const dashboard = renderDashboard(\n * [\n * { name: \"users\", path: \"users\", docCount: 150 },\n * { name: \"posts\", path: \"posts\", docCount: 42 },\n * ],\n * \"/admin\"\n * );\n *\n * // Render document list with pagination\n * const list = renderList(\n * \"users\",\n * [{ docId: \"1\", name: \"John\" }, { docId: \"2\", name: \"Jane\" }],\n * [\"docId\", \"name\"],\n * \"/admin\",\n * { hasPrev: false, hasNext: true, prevCursor: \"\", nextCursor: \"abc123\" },\n * { type: \"success\", message: \"User created!\" }, // Optional flash\n * [{ key: \"name\", label: \"Name\" }], // Column metadata\n * [{ field: \"name\", op: \"==\", value: \"John\" }], // Active filters\n * true, // Allow delete\n * [{ key: \"docId\", column: \"Posts\", targetRepo: \"posts\", targetKey: \"userId\", type: \"many\" }],\n * { field: \"name\", direction: \"asc\" }, // Sort state\n * 25, // Current page size\n * );\n *\n * // Render create/edit form page\n * const form = renderFormPage(\n * \"users\",\n * \"<form>...</form>\",\n * \"edit\",\n * \"user-123\",\n * \"/admin\",\n * { type: \"error\", message: \"Validation failed\" }\n * );\n * ```\n */\n\nexport { ClientScript } from \"./components\";\nexport type {\n ColumnMeta,\n FilterState,\n PageOptions,\n RelationalFieldMeta,\n SortState,\n WhereOp,\n} from \"./components\";\n\n/** @deprecated Styles come from DaisyUI CDN — no inline CSS needed */\nexport const CSS = \"\";\n\nimport type {\n ColumnMeta,\n FilterState,\n PageOptions,\n RelationalFieldMeta,\n SortState,\n} from \"./components\";\nimport {\n renderDashboardJsx,\n renderFormPageJsx,\n renderListJsx,\n renderPageJsx,\n} from \"./components\";\n\nexport function renderPage(content: string, opts: PageOptions): string {\n return renderPageJsx(content, opts);\n}\n\nexport function renderDashboard(\n repos: { name: string; path: string; docCount?: number }[],\n basePath: string,\n): string {\n return renderDashboardJsx(repos, basePath);\n}\n\nexport function renderList(\n repoName: string,\n docs: Record<string, unknown>[],\n columns: string[],\n basePath: string,\n pagination: {\n hasPrev: boolean;\n hasNext: boolean;\n prevCursor: string;\n nextCursor: string;\n },\n flash?: PageOptions[\"flash\"],\n columnMeta?: ColumnMeta[],\n activeFilters?: FilterState[],\n allowDelete?: boolean,\n relationalMeta?: RelationalFieldMeta[],\n sortState?: SortState,\n currentPageSize?: number,\n): string {\n return renderListJsx(\n repoName,\n docs,\n columns,\n basePath,\n pagination,\n flash,\n columnMeta,\n activeFilters,\n allowDelete,\n relationalMeta,\n sortState,\n currentPageSize,\n );\n}\n\nexport function renderFormPage(\n repoName: string,\n formHtml: string,\n mode: \"create\" | \"edit\",\n docId: string | null,\n basePath: string,\n flash?: PageOptions[\"flash\"],\n): string {\n return renderFormPageJsx(repoName, formHtml, mode, docId, basePath, flash);\n}\n","/**\n * HTTP route handlers for the admin ORM server.\n * Each handler corresponds to a URL pattern registered in the router.\n *\n * Routes:\n * GET / → dashboard GET /:repoName → document list (paginated)\n * GET /:repoName/create → create form\n * POST /:repoName/create → submit create\n * GET /:repoName/:id/edit → edit form (pre-filled)\n * POST /:repoName/:id/edit → submit update\n * POST /:repoName/:id/delete → delete document\n */\n\nimport { z } from \"zod\";\nimport type { ConfiguredRepository } from \"../../repositories/types\";\nimport type { RepositoryConfig } from \"../../shared/types\";\nimport { getInnerType, getShape, getTypeName } from \"../../shared/zod-compat\";\nimport { renderForm, zodToFields, type FieldDescriptor } from \"./form-gen\";\nimport type {\n ColumnMeta,\n FilterState,\n RelationalFieldMeta,\n WhereOp,\n} from \"./renderer\";\nimport { renderDashboard, renderFormPage, renderList } from \"./renderer\";\nimport type { AnyReq, AnyRes, RouteParams } from \"./router\";\n\n// ---------------------------------------------------------------------------\n// Registry type\n// ---------------------------------------------------------------------------\n\nexport interface AdminRepoEntry {\n name: string;\n path: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n repo: ConfiguredRepository<\n RepositoryConfig<any, any, any, any, any, any, any, any, any, any>\n >;\n schema: z.ZodObject<any>;\n /** document key field name (default: \"docId\") */\n documentKey?: string;\n /** Field name that stores the full Firestore document path (e.g. \"documentPath\") */\n pathKey?: string;\n /** Whether this repo is a collection group (subcollection) */\n isGroup?: boolean;\n /** Parent key field names needed to build a subcollection document ref (auto-detected from refCb) */\n parentKeys?: string[];\n /** Field name for the creation timestamp (auto-set on create) */\n createdKey?: string;\n /** List of columns to display in the table (defaults to schema keys) */\n listColumns?: string[];\n /** Page size for list view (default: 25) */\n pageSize?: number;\n /** Fields exposed in the filter bar (defaults to all schema keys) */\n filterableFields?: string[];\n /** Fields shown in the edit form (defaults to all schema fields if unset) */\n mutableFields?: string[];\n /** Fields shown in the create form (defaults to all schema fields if unset) */\n createFields?: string[];\n /** Whether delete is allowed (default: false) */\n allowDelete?: boolean;\n /**\n * Fields that link to another repository.\n * Populated automatically from the repo's relationalKeys.\n */\n relationalMeta?: RelationalFieldMeta[];\n}\n\nexport type RepoRegistry = Record<string, AdminRepoEntry>;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst _idChars =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\n/** Generate a random 20-char alphanumeric ID matching Firestore's native format. */\nfunction generateFirestoreId(): string {\n let id = \"\";\n for (let i = 0; i < 20; i++) {\n id += _idChars.charAt(Math.floor(Math.random() * _idChars.length));\n }\n return id;\n}\n\n/**\n * Extract Firestore document path args from a document's stored path.\n * e.g. \"posts/abc/comments/xyz\" → [\"abc\", \"xyz\"] (the doc-ID segments).\n * Returns `undefined` when no usable path is available.\n */\nfunction extractPathArgs(\n doc: Record<string, unknown>,\n pathKey?: string,\n): string[] | undefined {\n if (!pathKey) return undefined;\n const fullPath = doc[pathKey];\n if (typeof fullPath !== \"string\" || !fullPath) return undefined;\n const segments = fullPath.split(\"/\").filter(Boolean);\n // Doc IDs are at odd indices: col/id/col/id/...\n const args: string[] = [];\n for (let i = 1; i < segments.length; i += 2) {\n args.push(segments[i]!);\n }\n return args.length > 0 ? args : undefined;\n}\n\n/**\n * Fetch a single document by its documentKey, with fallback to query\n * for collection-group repos where direct documentRef may fail.\n */\nasync function fetchDocById(\n entry: AdminRepoEntry,\n docId: string,\n): Promise<Record<string, unknown> | null> {\n const docKey = entry.documentKey ?? \"docId\";\n const getMethod =\n `by${docKey.charAt(0).toUpperCase()}${docKey.slice(1)}` as keyof typeof entry.repo.get;\n\n // Try direct get first\n if (typeof entry.repo.get[getMethod] === \"function\") {\n try {\n const doc = (await (entry.repo.get[getMethod] as Function)(\n docId,\n )) as Record<string, unknown> | null;\n if (doc) return doc;\n } catch {\n // Direct ref may fail for subcollections — fall through to query\n }\n }\n\n // Fallback: query-based lookup (works for collectionGroup)\n const results = await entry.repo.query.by({\n where: [[docKey, \"==\", docId]],\n limit: 1,\n });\n return (results[0] as Record<string, unknown>) ?? null;\n}\n\nfunction sendHtml(res: AnyRes, html: string, status = 200): void {\n res.status(status).set(\"Content-Type\", \"text/html; charset=utf-8\").send(html);\n}\n\nfunction redirect(res: AnyRes, to: string): void {\n res.status(302).set(\"Location\", to).send(\"\");\n}\n\n/**\n * Parse a flat form body (from `application/x-www-form-urlencoded`) into a\n * typed object using the Zod schema as guide.\n * Handles: dot-notation nested fields (e.g. address.street), JSON textarea\n * values, booleans (checkbox), numbers.\n */\nfunction parseFormBody(\n raw: Record<string, string | string[] | undefined>,\n schema: z.ZodObject<any>,\n): Record<string, unknown> {\n const shape = schema.shape;\n const result: Record<string, unknown> = {};\n\n for (const [key, zodField] of Object.entries(shape)) {\n const tn = resolveTypeName(zodField as z.ZodType);\n\n // ── ZodObject: prefer dot-notation sub-keys over raw JSON textarea ──────\n if (tn === \"ZodObject\") {\n // Check for explicit null marker first\n if (raw[key + \"__isnull\"] === \"1\") {\n result[key] = null;\n continue;\n }\n const subRaw: Record<string, string | string[] | undefined> = {};\n let hasDotKeys = false;\n for (const [k, v] of Object.entries(raw)) {\n if (k.startsWith(`${key}.`)) {\n subRaw[k.slice(key.length + 1)] = v;\n hasDotKeys = true;\n }\n }\n if (hasDotKeys) {\n // Unwrap to the inner ZodObject schema and recurse\n let innerSchema: z.ZodType = zodField as z.ZodType;\n while (true) {\n const itn = getTypeName(innerSchema);\n if (\n itn === \"ZodOptional\" ||\n itn === \"ZodNullable\" ||\n itn === \"ZodDefault\"\n ) {\n innerSchema = getInnerType(innerSchema)!;\n } else break;\n }\n result[key] = parseFormBody(subRaw, innerSchema as z.ZodObject<any>);\n continue;\n }\n // Fallback: try to JSON-parse the textarea value\n const rawVal = raw[key];\n const strVal = Array.isArray(rawVal) ? rawVal[rawVal.length - 1] : rawVal;\n if (strVal) {\n try {\n result[key] = JSON.parse(strVal);\n } catch {\n result[key] = strVal;\n }\n }\n continue;\n }\n\n // ── All other types ─────────────────────────────────────────────────────\n const rawVal = raw[key];\n const strVal = Array.isArray(rawVal) ? rawVal[rawVal.length - 1] : rawVal;\n // Nullable field explicitly set to null via the toggle\n if (raw[key + \"__isnull\"] === \"1\") {\n result[key] = null;\n continue;\n }\n if (strVal === undefined || strVal === \"\") {\n // Checkbox unchecked → false; everything else → omit\n if (tn === \"ZodBoolean\") result[key] = false;\n continue;\n }\n\n switch (tn) {\n case \"ZodBoolean\":\n if (strVal === \"__null__\") {\n result[key] = null;\n } else {\n result[key] = strVal === \"true\" || strVal === \"on\" || strVal === \"1\";\n }\n break;\n case \"ZodNumber\":\n case \"ZodBigInt\":\n result[key] = Number(strVal);\n break;\n case \"ZodDate\":\n result[key] = new Date(strVal);\n break;\n case \"ZodArray\":\n try {\n result[key] = JSON.parse(strVal);\n } catch {\n result[key] = strVal;\n }\n break;\n default:\n // Try JSON for inline JSON textareas, fall back to string\n if (strVal.startsWith(\"{\") || strVal.startsWith(\"[\")) {\n try {\n result[key] = JSON.parse(strVal);\n break;\n } catch {\n /* fall through */\n }\n }\n result[key] = strVal;\n }\n }\n\n return result;\n}\n\n/**\n * Convert any date-like value to the \"yyyy-MM-ddThh:mm\" string required by\n * `<input type=\"datetime-local\">`.\n * Handles: native Date, Firestore Timestamp ({_seconds, _nanoseconds}),\n * Firestore Timestamp with .toDate(), ISO strings, unix numbers.\n */\nfunction toDatetimeLocal(val: unknown): string | null {\n let date: Date | null = null;\n\n if (val instanceof Date) {\n date = val;\n } else if (\n typeof val === \"object\" &&\n val !== null &&\n typeof (val as any).toDate === \"function\"\n ) {\n // Firestore Timestamp SDK object\n date = (val as any).toDate() as Date;\n } else if (\n typeof val === \"object\" &&\n val !== null &&\n \"_seconds\" in val &&\n \"_nanoseconds\" in val\n ) {\n // Plain serialized Firestore Timestamp { _seconds, _nanoseconds }\n date = new Date(\n (val as any)._seconds * 1000 +\n Math.floor((val as any)._nanoseconds / 1_000_000),\n );\n } else if (typeof val === \"string\" || typeof val === \"number\") {\n const d = new Date(val as string | number);\n if (!isNaN(d.getTime())) date = d;\n }\n\n if (!date || isNaN(date.getTime())) return null;\n\n // Format as local time yyyy-MM-ddThh:mm (what datetime-local expects)\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return (\n `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}` +\n `T${pad(date.getHours())}:${pad(date.getMinutes())}`\n );\n}\n\n/** Resolve the innermost Zod type name (unwrapping Optional/Nullable/Default) */\nfunction resolveTypeName(schema: z.ZodType): string {\n let s: z.ZodType = schema;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const tn = getTypeName(s);\n if (tn === \"ZodOptional\" || tn === \"ZodNullable\" || tn === \"ZodDefault\") {\n s = getInnerType(s)!;\n } else {\n return tn;\n }\n }\n}\n\n/**\n * Prefill a Zod schema fields with existing document values.\n * For ZodObject fields, recurses into nested sub-fields using dot-notation keys\n * so that individual sub-inputs (e.g. address.street) are properly pre-filled.\n */\nfunction prefillFromDoc(\n doc: Record<string, unknown>,\n schema: z.ZodObject<any>,\n prefix = \"\",\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const key of Object.keys(schema.shape)) {\n const fullKey = prefix ? `${prefix}.${key}` : key;\n const val = doc[key];\n // Sentinel \"__null__\" tells renderField to pre-check the null toggle\n if (val === null) {\n result[fullKey] = \"__null__\";\n continue;\n }\n if (val === undefined) continue;\n\n // Unwrap Optional/Nullable/Default to check inner type\n let innerSchema: z.ZodType = schema.shape[key] as z.ZodType;\n while (true) {\n const itn = getTypeName(innerSchema);\n if (\n itn === \"ZodOptional\" ||\n itn === \"ZodNullable\" ||\n itn === \"ZodDefault\"\n ) {\n innerSchema = getInnerType(innerSchema)!;\n } else break;\n }\n const innerTn = getTypeName(innerSchema);\n\n if (\n innerTn === \"ZodObject\" &&\n typeof val === \"object\" &&\n val !== null &&\n !Array.isArray(val)\n ) {\n // Recursively flatten nested object fields with dot-notation\n const nested = prefillFromDoc(\n val as Record<string, unknown>,\n innerSchema as z.ZodObject<any>,\n fullKey,\n );\n Object.assign(result, nested);\n } else if (innerTn === \"ZodDate\") {\n // Convert Date / Firestore Timestamp → datetime-local string\n const dtLocal = toDatetimeLocal(val);\n if (dtLocal !== null) result[fullKey] = dtLocal;\n } else if (\n typeof val === \"object\" &&\n val !== null &&\n !Array.isArray(val) &&\n (\"_seconds\" in val || typeof (val as any).toDate === \"function\")\n ) {\n // Untyped Timestamp-like value: try datetime-local, fall back to JSON\n const dtLocal = toDatetimeLocal(val);\n result[fullKey] = dtLocal ?? JSON.stringify(val, null, 2);\n } else if (typeof val === \"object\") {\n result[fullKey] = JSON.stringify(val, null, 2);\n } else {\n result[fullKey] = String(val);\n }\n }\n return result;\n}\n\n/**\n * Recursively apply prefilled string values to a tree of FieldDescriptors.\n * Handles dot-notation keys for nested objects (e.g. \"address.street\").\n */\nfunction applyPrefill(\n fields: FieldDescriptor[],\n prefilled: Record<string, string>,\n): FieldDescriptor[] {\n return fields.map((f) => ({\n ...f,\n defaultValue: prefilled[f.name] ?? f.defaultValue,\n nested: f.nested ? applyPrefill(f.nested, prefilled) : undefined,\n }));\n}\n\n// ---------------------------------------------------------------------------\n// Filter helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Extract active filters from URL query params.\n * Params: fv_{field} = value, fo_{field} = operator (default ==)\n */\nfunction parseFilters(\n query: Record<string, string>,\n validFields: Set<string>,\n): FilterState[] {\n const validOps = new Set<string>([\n \"==\",\n \"!=\",\n \"<\",\n \"<=\",\n \">\",\n \">=\",\n \"array-contains\",\n \"array-contains-any\",\n ]);\n const filters: FilterState[] = [];\n for (const [k, v] of Object.entries(query)) {\n if (!k.startsWith(\"fv_\")) continue;\n const field = k.slice(3);\n if (!validFields.has(field)) continue;\n const value = (v ?? \"\").trim();\n if (!value) continue;\n const opRaw = query[`fo_${field}`] ?? \"==\";\n const op = validOps.has(opRaw) ? (opRaw as WhereOp) : \"==\";\n filters.push({ field, op, value });\n }\n return filters;\n}\n\n/**\n * Convert FilterState[] to the where-clause tuples expected by the query engine.\n * Coerces string values to boolean/number when unambiguous.\n */\nfunction filtersToWhere(filters: FilterState[]): [string, WhereOp, unknown][] {\n const coerce = (v: string): unknown => {\n if (v === \"true\") return true;\n if (v === \"false\") return false;\n if (v !== \"\" && !isNaN(Number(v))) return Number(v);\n return v;\n };\n return filters.map((f) => {\n if (f.op === \"array-contains-any\") {\n // CSV list → array, each element coerced\n const arr = f.value\n .split(\",\")\n .map((s) => coerce(s.trim()))\n .filter((s) => s !== \"\");\n return [f.field, f.op, arr];\n }\n return [f.field, f.op, coerce(f.value)];\n });\n}\n\n/** Build ColumnMeta for displayable columns, recursing into ZodObject sub-fields (dot-notation). */\nfunction buildColumnMeta(\n columns: string[],\n schema: z.ZodObject<any>,\n prefix = \"\",\n): ColumnMeta[] {\n const result: ColumnMeta[] = [];\n for (const col of columns) {\n const fullName = prefix ? `${prefix}.${col}` : col;\n const field = schema.shape[col] as z.ZodType | undefined;\n if (!field) {\n result.push({ name: fullName, zodType: \"ZodString\" });\n continue;\n }\n const zodType = resolveTypeName(field);\n if (zodType === \"ZodObject\") {\n // Unwrap wrappers to reach the inner ZodObject\n let inner: z.ZodType = field;\n while (true) {\n const itn = getTypeName(inner);\n if (\n itn === \"ZodOptional\" ||\n itn === \"ZodNullable\" ||\n itn === \"ZodDefault\"\n ) {\n inner = getInnerType(inner)!;\n } else break;\n }\n const subShape = getShape(inner);\n result.push(\n ...buildColumnMeta(\n Object.keys(subShape),\n inner as z.ZodObject<any>,\n fullName,\n ),\n );\n } else {\n result.push({ name: fullName, zodType });\n }\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Handler factory\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the ZodType at a dot-notation path (e.g. \"address.city\") within a schema.\n * Returns null if the path cannot be resolved.\n */\nfunction resolveZodAtPath(\n schema: z.ZodObject<any>,\n path: string,\n): z.ZodType | null {\n const parts = path.split(\".\");\n let s: z.ZodType = schema as z.ZodType;\n for (const part of parts) {\n // Unwrap Optional / Nullable / Default wrappers\n while (true) {\n const itn = getTypeName(s);\n if (\n itn === \"ZodOptional\" ||\n itn === \"ZodNullable\" ||\n itn === \"ZodDefault\"\n ) {\n s = getInnerType(s)!;\n } else break;\n }\n const shape = getShape(s);\n if (!(part in shape)) return null;\n s = shape[part]!;\n }\n return s;\n}\n\n/**\n * Returns a Zod schema restricted to `fields` when defined.\n * Supports dot-notation paths (e.g. \"address.city\") by building partial\n * nested sub-schemas — useful for edit/create forms.\n * Falls back to the full schema if fields is undefined/empty.\n */\nfunction getMutableSchema(\n schema: z.ZodObject<any>,\n fields: string[] | undefined,\n): z.ZodObject<any> {\n if (!fields || fields.length === 0) return schema;\n\n const topLevel: string[] = [];\n // parent key → list of sub-field names requested\n const dotGroups = new Map<string, string[]>();\n\n for (const f of fields) {\n const dot = f.indexOf(\".\");\n if (dot === -1) {\n topLevel.push(f);\n } else {\n const parent = f.slice(0, dot);\n const child = f.slice(dot + 1);\n if (!dotGroups.has(parent)) dotGroups.set(parent, []);\n dotGroups.get(parent)!.push(child);\n }\n }\n\n const picked: Record<string, z.ZodType> = {};\n\n // Direct top-level fields\n for (const f of topLevel) {\n if (f in schema.shape) picked[f] = schema.shape[f]!;\n }\n\n // Partial nested objects for dot-notation entries\n for (const [parent, subFields] of dotGroups) {\n if (!(parent in schema.shape)) continue;\n // Unwrap to the inner ZodObject\n let inner: z.ZodType = schema.shape[parent] as z.ZodType;\n while (true) {\n const itn = getTypeName(inner);\n if (\n itn === \"ZodOptional\" ||\n itn === \"ZodNullable\" ||\n itn === \"ZodDefault\"\n ) {\n inner = getInnerType(inner)!;\n } else break;\n }\n if (getTypeName(inner) !== \"ZodObject\") {\n // Not an object — include as-is\n picked[parent] = schema.shape[parent]!;\n continue;\n }\n // Recurse: build a partial sub-schema for the requested sub-fields\n picked[parent] = getMutableSchema(inner as z.ZodObject<any>, subFields);\n }\n\n return z.object(picked);\n}\n/**\n * Compute the link base for all UI links.\n *\n * ── Emulator (FUNCTIONS_EMULATOR=true) ──────────────────────────────────────\n * Firebase emulator exposes functions at:\n * http://localhost:5001/{GCLOUD_PROJECT}/{FUNCTION_REGION}/{FUNCTION_TARGET}/...\n * env vars set by the emulator:\n * GCLOUD_PROJECT / GOOGLE_CLOUD_PROJECT → project id\n * FUNCTION_REGION → region (default: us-central1)\n * FUNCTION_TARGET → function export name (e.g. \"admin\")\n *\n * ── Production ──────────────────────────────────────────────────────────────\n * Firebase proxy strips the prefix before reaching the handler, so links\n * are relative to \"/\" and `staticBasePath` is used as-is.\n */\nfunction getLinkBase(req: AnyReq, staticBasePath: string): string {\n const base = staticBasePath === \"/\" ? \"\" : staticBasePath.replace(/\\/$/, \"\");\n\n if (process.env[\"FUNCTIONS_EMULATOR\"] === \"true\") {\n const project =\n process.env[\"GCLOUD_PROJECT\"] ??\n process.env[\"GOOGLE_CLOUD_PROJECT\"] ??\n \"demo-project\";\n const region = process.env[\"FUNCTION_REGION\"] ?? \"us-central1\";\n // FUNCTION_TARGET uses dots (e.g. \"sync.functions.syncAdmin\") but the\n // emulator URL uses hyphens (\"sync-functions-syncAdmin\").\n const target = (process.env[\"FUNCTION_TARGET\"] ?? \"\").replace(/\\./g, \"-\");\n return `/${project}/${region}/${target}${base}`;\n }\n\n // Cloud Functions v2: K_SERVICE = function name = URL path prefix.\n // Only add it when accessed via cloudfunctions.net (not custom domains).\n const service = process.env[\"K_SERVICE\"];\n const host: string =\n (req as any).hostname ?? (req.headers as any)?.[\"host\"] ?? \"\";\n if (service && host.includes(\"cloudfunctions.net\")) {\n return `/${service}${base}`;\n }\n\n return base;\n}\n\nexport function createAdminHandlers(registry: RepoRegistry, basePath: string) {\n // ── Dashboard ─────────────────────────────────────────────────────────────\n const handleDashboard = (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n ): void => {\n const lb = getLinkBase(req, basePath);\n const repos = Object.values(registry).map((e) => ({\n name: e.name,\n path: e.path,\n }));\n sendHtml(res, renderDashboard(repos, lb));\n };\n\n // ── List documents ────────────────────────────────────────────────────────\n const handleList = async (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n ): Promise<void> => {\n const repoName = req.params[\"repoName\"];\n if (!repoName) {\n sendHtml(res, \"Bad request\", 400);\n return;\n }\n const entry = registry[repoName];\n if (!entry) {\n sendHtml(res, \"Repository not found\", 404);\n return;\n }\n\n const pageSize = entry.pageSize ?? 25;\n const query = (req.query ?? {}) as Record<string, string>;\n const cursorStr = query[\"cursor\"];\n const dir = query[\"dir\"] === \"prev\" ? \"prev\" : \"next\";\n\n // Sort\n const sortField = query[\"ob\"] ?? \"\";\n const sortDir = (query[\"od\"] === \"desc\" ? \"desc\" : \"asc\") as \"asc\" | \"desc\";\n const sortState = sortField\n ? { field: sortField, dir: sortDir }\n : undefined;\n\n // Rows per page (query ?ps= overrides config, capped at 200)\n const psRaw = parseInt(query[\"ps\"] ?? \"\");\n const currentPageSize =\n Number.isFinite(psRaw) && psRaw > 0 ? Math.min(psRaw, 200) : pageSize;\n\n const allColumns = entry.listColumns ?? Object.keys(entry.schema.shape);\n const docKey = entry.documentKey ?? \"docId\";\n const columns = [docKey, ...allColumns.filter((c: string) => c !== docKey)];\n // Restrict filterable columns to filterableFields when defined.\n // Dot-notation paths (e.g. \"address.city\") are passed through directly;\n // top-level keys expand to sub-fields via buildColumnMeta as before.\n const filterableColumns: string[] = entry.filterableFields\n ? (() => {\n const out: string[] = [];\n for (const f of entry.filterableFields!) {\n if (f.includes(\".\")) {\n out.push(f); // direct dot-notation path\n } else if (allColumns.includes(f)) {\n out.push(f); // regular top-level key\n }\n }\n return out;\n })()\n : allColumns;\n // For dot-notation entries, resolve the correct ZodType; for top-level\n // keys, delegate to the existing buildColumnMeta (handles ZodObject expansion).\n const columnMeta: import(\"./renderer\").ColumnMeta[] = (() => {\n const out: import(\"./renderer\").ColumnMeta[] = [];\n for (const col of filterableColumns) {\n if (col.includes(\".\")) {\n const resolved = resolveZodAtPath(entry.schema, col);\n out.push({\n name: col,\n zodType: resolved ? resolveTypeName(resolved) : \"ZodString\",\n });\n } else {\n out.push(...buildColumnMeta([col], entry.schema));\n }\n }\n return out;\n })();\n\n // Parse and validate filters from query params\n // validFields built from columnMeta so dot-notation fields (address.city) are accepted\n const validFields = new Set(columnMeta.map((c) => c.name));\n const activeFilters = parseFilters(query, validFields);\n const whereFilters = filtersToWhere(activeFilters);\n\n // Attempt to rehydrate cursor\n let cursorSnapshot:\n | import(\"firebase-admin/firestore\").DocumentSnapshot\n | undefined;\n if (cursorStr) {\n try {\n const colRef = entry.repo.ref as any;\n if (typeof colRef.doc === \"function\") {\n cursorSnapshot = await colRef.doc(cursorStr).get();\n }\n } catch {\n /* ignore */\n }\n }\n\n const result = await entry.repo.query.paginate({\n pageSize: currentPageSize,\n cursor: cursorSnapshot,\n // direction + where + orderBy are supported at runtime but not in the strict typed interface\n ...{ direction: dir },\n ...(whereFilters.length > 0 ? { where: whereFilters } : {}),\n ...(sortState\n ? {\n orderBy: [\n { field: sortState.field as any, direction: sortState.dir },\n ],\n }\n : {}),\n });\n\n const nextCursorId = result.nextCursor?.id ?? \"\";\n const prevCursorId = result.prevCursor?.id ?? \"\";\n const lb = getLinkBase(req, basePath);\n\n sendHtml(\n res,\n renderList(\n entry.name,\n result.data as Record<string, unknown>[],\n columns,\n lb,\n {\n hasPrev: result.hasPrevPage,\n hasNext: result.hasNextPage,\n prevCursor: prevCursorId,\n nextCursor: nextCursorId,\n },\n undefined,\n columnMeta,\n activeFilters,\n entry.allowDelete ?? false,\n entry.relationalMeta,\n sortState,\n currentPageSize,\n ),\n );\n };\n\n // ── Create form ───────────────────────────────────────────────────────────\n const handleCreateForm = (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n ): void => {\n const repoName = req.params[\"repoName\"];\n if (!repoName) {\n sendHtml(res, \"Bad request\", 400);\n return;\n }\n const entry = registry[repoName];\n if (!entry) {\n sendHtml(res, \"Repository not found\", 404);\n return;\n }\n\n const lb = getLinkBase(req, basePath);\n const createSchema = getMutableSchema(entry.schema, entry.createFields);\n const fields = zodToFields(createSchema);\n const actionUrl = `${lb}/${entry.name}/create`;\n const formHtml = renderForm(fields, actionUrl, \"POST\", \"Create document\");\n\n sendHtml(res, renderFormPage(entry.name, formHtml, \"create\", null, lb));\n };\n\n // ── Create submit ─────────────────────────────────────────────────────────\n const handleCreateSubmit = async (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n ): Promise<void> => {\n const repoName = req.params[\"repoName\"];\n if (!repoName) {\n sendHtml(res, \"Bad request\", 400);\n return;\n }\n const entry = registry[repoName];\n if (!entry) {\n sendHtml(res, \"Repository not found\", 404);\n return;\n }\n\n const lb = getLinkBase(req, basePath);\n const rawBody =\n (req.body as Record<string, string | string[] | undefined>) ?? {};\n const parsed = parseFormBody(rawBody, entry.schema);\n const createSchema = getMutableSchema(entry.schema, entry.createFields);\n const validation = createSchema.safeParse(parsed);\n\n if (!validation.success) {\n const fields = zodToFields(createSchema);\n const actionUrl = `${lb}/${entry.name}/create`;\n const formHtml = renderForm(fields, actionUrl, \"POST\", \"Create document\");\n const errorMsg = validation.error.issues\n .map((e) => `${e.path.join(\".\")}: ${e.message}`)\n .join(\", \");\n sendHtml(\n res,\n renderFormPage(entry.name, formHtml, \"create\", null, lb, {\n type: \"error\",\n message: `Validation error: ${errorMsg}`,\n }),\n 422,\n );\n return;\n }\n\n try {\n if (entry.isGroup && entry.parentKeys && entry.parentKeys.length > 0) {\n // Collection-group repos cannot use create(); use set() with parent path args.\n const data: Record<string, any> = { ...validation.data };\n // set() doesn't auto-set createdKey, so inject it here\n if (entry.createdKey) {\n data[entry.createdKey] = new Date();\n }\n const missingKeys = entry.parentKeys.filter((k) => !data[k]);\n if (missingKeys.length > 0) {\n throw new Error(\n `Missing parent key(s) for subcollection create: ${missingKeys.join(\", \")}`,\n );\n }\n const parentIds = entry.parentKeys.map((k) => data[k] as string);\n const docKey = entry.documentKey ?? \"docId\";\n const docId = data[docKey] || generateFirestoreId();\n await entry.repo.set(...parentIds, docId, data);\n } else {\n await entry.repo.create(validation.data);\n }\n redirect(res, `${lb}/${entry.name}?flash=created`);\n } catch (err) {\n const createSchema2 = getMutableSchema(entry.schema, entry.createFields);\n const fields = zodToFields(createSchema2);\n const actionUrl = `${lb}/${entry.name}/create`;\n const formHtml = renderForm(fields, actionUrl, \"POST\", \"Create document\");\n sendHtml(\n res,\n renderFormPage(entry.name, formHtml, \"create\", null, lb, {\n type: \"error\",\n message: `Save error: ${(err as Error).message}`,\n }),\n 500,\n );\n }\n };\n\n // ── Edit form ─────────────────────────────────────────────────────────────\n const handleEditForm = async (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n ): Promise<void> => {\n const repoName = req.params[\"repoName\"];\n const docId = req.params[\"id\"];\n if (!repoName || !docId) {\n sendHtml(res, \"Bad request\", 400);\n return;\n }\n const entry = registry[repoName];\n if (!entry) {\n sendHtml(res, \"Repository not found\", 404);\n return;\n }\n\n let doc: Record<string, unknown> | null = null;\n try {\n doc = await fetchDocById(entry, docId);\n } catch (err) {\n sendHtml(res, `Error fetching document: ${(err as Error).message}`, 500);\n return;\n }\n\n if (!doc) {\n sendHtml(res, \"Document not found\", 404);\n return;\n }\n\n const prefilled = prefillFromDoc(doc, entry.schema);\n const mutableSchema = getMutableSchema(entry.schema, entry.mutableFields);\n const fields = applyPrefill(zodToFields(mutableSchema), prefilled);\n\n const lb = getLinkBase(req, basePath);\n const actionUrl = `${lb}/${entry.name}/${encodeURIComponent(docId)}/edit`;\n const formHtml = renderForm(fields, actionUrl, \"POST\", \"Save changes\");\n\n sendHtml(res, renderFormPage(entry.name, formHtml, \"edit\", docId, lb));\n };\n\n // ── Edit submit ───────────────────────────────────────────────────────────\n const handleEditSubmit = async (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n ): Promise<void> => {\n const repoName = req.params[\"repoName\"];\n const docId = req.params[\"id\"];\n if (!repoName || !docId) {\n sendHtml(res, \"Bad request\", 400);\n return;\n }\n const entry = registry[repoName];\n if (!entry) {\n sendHtml(res, \"Repository not found\", 404);\n return;\n }\n const lb = getLinkBase(req, basePath);\n const rawBody =\n (req.body as Record<string, string | string[] | undefined>) ?? {};\n const parsed = parseFormBody(rawBody, entry.schema);\n\n // Partial validation for updates (restricted to mutableFields)\n const mutableSchema = getMutableSchema(entry.schema, entry.mutableFields);\n const partialSchema = mutableSchema.partial();\n const validation = partialSchema.safeParse(parsed);\n\n if (!validation.success) {\n const prefilled = Object.fromEntries(\n Object.entries(rawBody).map(([k, v]) => [\n k,\n Array.isArray(v) ? v.join(\",\") : (v ?? \"\"),\n ]),\n );\n const fields = applyPrefill(zodToFields(mutableSchema), prefilled);\n const actionUrl = `${lb}/${entry.name}/${encodeURIComponent(docId)}/edit`;\n const formHtml = renderForm(fields, actionUrl, \"POST\", \"Save changes\");\n const errorMsg = validation.error.issues\n .map((e) => `${e.path.join(\".\")}: ${e.message}`)\n .join(\", \");\n sendHtml(\n res,\n renderFormPage(entry.name, formHtml, \"edit\", docId, lb, {\n type: \"error\",\n message: `Validation error: ${errorMsg}`,\n }),\n 422,\n );\n return;\n }\n\n try {\n // Fetch document to extract path args for subcollection repos\n const doc = await fetchDocById(entry, docId);\n const pathArgs = (doc && extractPathArgs(doc, entry.pathKey)) ?? [docId];\n await entry.repo.update(...pathArgs, validation.data);\n redirect(res, `${lb}/${entry.name}?flash=updated`);\n } catch (err) {\n const mutableSchema2 = getMutableSchema(\n entry.schema,\n entry.mutableFields,\n );\n const fields = zodToFields(mutableSchema2);\n const actionUrl = `${lb}/${entry.name}/${encodeURIComponent(docId)}/edit`;\n const formHtml = renderForm(fields, actionUrl, \"POST\", \"Save changes\");\n sendHtml(\n res,\n renderFormPage(entry.name, formHtml, \"edit\", docId, lb, {\n type: \"error\",\n message: `Save error: ${(err as Error).message}`,\n }),\n 500,\n );\n }\n };\n\n // ── Delete ────────────────────────────────────────────────────────────────\n const handleDelete = async (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n ): Promise<void> => {\n const repoName = req.params[\"repoName\"];\n const docId = req.params[\"id\"];\n if (!repoName || !docId) {\n sendHtml(res, \"Bad request\", 400);\n return;\n }\n const entry = registry[repoName];\n if (!entry) {\n sendHtml(res, \"Repository not found\", 404);\n return;\n }\n if (!entry.allowDelete) {\n sendHtml(res, \"Delete is not allowed for this repository\", 403);\n return;\n }\n const lb = getLinkBase(req, basePath);\n try {\n // Fetch document to extract path args for subcollection repos\n const doc = await fetchDocById(entry, docId);\n const pathArgs = (doc && extractPathArgs(doc, entry.pathKey)) ?? [docId];\n await entry.repo.delete(...pathArgs);\n redirect(res, `${lb}/${entry.name}?flash=deleted`);\n } catch (err) {\n sendHtml(res, `Delete error: ${(err as Error).message}`, 500);\n }\n };\n\n return {\n handleDashboard,\n handleList,\n handleCreateForm,\n handleCreateSubmit,\n handleEditForm,\n handleEditSubmit,\n handleDelete,\n };\n}\n","/**\n * Minimal zero-dependency HTTP router for Firebase Functions.\n * Compatible with any Express-like (req, res) handler.\n *\n * Supports:\n * - Named path parameters (e.g. \"/repos/:name/:id\")\n * - GET, POST, DELETE methods\n * - Global middleware (before each route)\n * - 404 / error fallbacks\n *\n * @example\n * ```typescript\n * import { MiniRouter } from \"@lpdjs/firestore-repo-service/servers/admin\";\n *\n * // Create router\n * const router = new MiniRouter();\n *\n * // Add global middleware (executed before every route)\n * router.use(async (req, res, next) => {\n * console.log(`${req.method} ${req.url}`);\n * await next();\n * });\n *\n * // Auth middleware\n * router.use((req, res, next) => {\n * if (!req.headers?.authorization) {\n * res.status(401).send(\"Unauthorized\");\n * return;\n * }\n * next();\n * });\n *\n * // Define routes with path parameters\n * router.get(\"/users\", async (req, res) => {\n * res.json({ users: await getAllUsers() });\n * });\n *\n * router.get(\"/users/:id\", async (req, res) => {\n * const user = await getUser(req.params.id); // Access path params\n * if (!user) {\n * res.status(404).send(\"User not found\");\n * return;\n * }\n * res.json(user);\n * });\n *\n * router.post(\"/users\", async (req, res) => {\n * const user = await createUser(req.body);\n * res.status(201).json(user);\n * });\n *\n * router.delete(\"/users/:id\", async (req, res) => {\n * await deleteUser(req.params.id);\n * res.status(204).end();\n * });\n *\n * // Custom 404 handler\n * router.onNotFound((req, res) => {\n * res.status(404).json({ error: \"Route not found\", path: req.url });\n * });\n *\n * // Custom error handler\n * router.onError((err, req, res) => {\n * console.error(\"Error:\", err);\n * res.status(500).json({ error: \"Internal server error\" });\n * });\n *\n * // Use with Firebase Functions\n * export const api = onRequest(async (req, res) => {\n * await router.handle(req, res);\n * });\n * ```\n */\n\nexport type AnyReq = {\n method?: string;\n url?: string;\n /** Express originalUrl — preserved before any router stripping, contains the full path including the Firebase Functions prefix */\n originalUrl?: string;\n path?: string;\n headers?: Record<string, string | string[] | undefined>;\n body?: unknown;\n query?: Record<string, string | string[] | undefined>;\n};\n\nexport type AnyRes = {\n status: (code: number) => AnyRes;\n set: (key: string, value: string) => AnyRes;\n send: (body: string) => void;\n json: (body: unknown) => void;\n end: () => void;\n};\n\nexport type RouteParams = Record<string, string>;\n\nexport type RouteHandler = (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n) => void | Promise<void>;\n\nexport type Middleware = (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n next: () => void | Promise<void>,\n) => void | Promise<void>;\n\n// ---------------------------------------------------------------------------\n// Route matching\n// ---------------------------------------------------------------------------\n\ninterface CompiledRoute {\n method: string;\n pattern: RegExp;\n paramNames: string[];\n handler: RouteHandler;\n}\n\nfunction compilePath(path: string): { pattern: RegExp; paramNames: string[] } {\n const paramNames: string[] = [];\n const src = path\n .replace(/[.*+?^${}()|[\\]\\\\]/g, (c) => (c === \":\" ? c : `\\\\${c}`))\n .replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_match, name: string) => {\n paramNames.push(name);\n return \"([^/]+)\";\n });\n\n return { pattern: new RegExp(`^${src}$`), paramNames };\n}\n\nfunction extractPath(req: AnyReq): string {\n const raw = req.path ?? req.url ?? \"/\";\n const idx = raw.indexOf(\"?\");\n return idx === -1 ? raw : raw.slice(0, idx);\n}\n\n// ---------------------------------------------------------------------------\n// Router class\n// ---------------------------------------------------------------------------\n\nexport class MiniRouter {\n private routes: CompiledRoute[] = [];\n private middlewares: Middleware[] = [];\n private notFoundHandler: RouteHandler = (_req, res) => {\n res.status(404).send(\"Not Found\");\n };\n private errorHandler: (err: unknown, req: AnyReq, res: AnyRes) => void = (\n err,\n _req,\n res,\n ) => {\n console.error(\"[MiniRouter]\", err);\n res.status(500).send(\"Internal Server Error\");\n };\n\n // ── Route registration ────────────────────────────────────────────────────\n\n use(middleware: Middleware): this {\n this.middlewares.push(middleware);\n return this;\n }\n\n get(path: string, handler: RouteHandler): this {\n return this.addRoute(\"GET\", path, handler);\n }\n\n post(path: string, handler: RouteHandler): this {\n return this.addRoute(\"POST\", path, handler);\n }\n\n put(path: string, handler: RouteHandler): this {\n return this.addRoute(\"PUT\", path, handler);\n }\n\n patch(path: string, handler: RouteHandler): this {\n return this.addRoute(\"PATCH\", path, handler);\n }\n\n delete(path: string, handler: RouteHandler): this {\n return this.addRoute(\"DELETE\", path, handler);\n }\n\n onNotFound(handler: RouteHandler): this {\n this.notFoundHandler = handler;\n return this;\n }\n\n onError(handler: (err: unknown, req: AnyReq, res: AnyRes) => void): this {\n this.errorHandler = handler;\n return this;\n }\n\n private addRoute(method: string, path: string, handler: RouteHandler): this {\n const { pattern, paramNames } = compilePath(path);\n this.routes.push({\n method: method.toUpperCase(),\n pattern,\n paramNames,\n handler,\n });\n return this;\n }\n\n // ── Dispatch ──────────────────────────────────────────────────────────────\n\n async handle(req: AnyReq, res: AnyRes): Promise<void> {\n const method = (req.method ?? \"GET\").toUpperCase();\n const path = extractPath(req);\n\n // Find matching route\n let matchedRoute: CompiledRoute | null = null;\n let params: RouteParams = {};\n\n for (const route of this.routes) {\n if (route.method !== method) continue;\n const m = path.match(route.pattern);\n if (m) {\n matchedRoute = route;\n params = {};\n route.paramNames.forEach((name, i) => {\n params[name] = decodeURIComponent(m[i + 1] ?? \"\");\n });\n break;\n }\n }\n\n const enrichedReq = Object.assign(req, { params });\n\n // Run middleware chain → then handler\n const handler = matchedRoute ? matchedRoute.handler : this.notFoundHandler;\n\n try {\n await this.runMiddlewareChain(enrichedReq, res, handler);\n } catch (err) {\n this.errorHandler(err, req, res);\n }\n }\n\n private async runMiddlewareChain(\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n finalHandler: RouteHandler,\n ): Promise<void> {\n let index = 0;\n\n const next = async (): Promise<void> => {\n if (index < this.middlewares.length) {\n const mw = this.middlewares[index++]!;\n await mw(req, res, next);\n } else {\n await finalHandler(req, res);\n }\n };\n\n await next();\n }\n}\n","/**\n * @module servers/admin\n *\n * Creates a static ORM admin interface served as a Firebase HTTPS function.\n *\n * Features:\n * - Dashboard listing all registered repositories\n * - Document list with cursor-based pagination\n * - Create / Edit / Delete forms generated from Zod schemas\n * - Forms map **exactly** to the repository model type\n * - Zero JavaScript framework — plain HTML + inline CSS + vanilla JS\n * - Body parsing for `application/x-www-form-urlencoded` (default HTML forms)\n * and `application/json` (API clients)\n *\n * @example\n * ```ts\n * import * as functions from \"firebase-functions\";\n * import { z } from \"zod\";\n * import { createAdminServer } from \"@lpdjs/firestore-repo-service/servers/admin\";\n *\n * const postSchema = z.object({\n * title: z.string().min(1),\n * content: z.string(),\n * status: z.enum([\"draft\", \"published\"]),\n * authorId: z.string(),\n * });\n *\n * export const adminApp = functions.https.onRequest(\n * createAdminServer({\n * basePath: \"/admin\",\n * repos: {\n * posts: { repo: repos.posts, schema: postSchema, path: \"posts\" },\n * },\n * })\n * );\n * ```\n */\n\nimport type { z } from \"zod\";\nimport type { ConfiguredRepository } from \"../../repositories/types\";\nimport type { FieldPath, RepositoryConfig } from \"../../shared/types\";\nimport type { FieldRole } from \"../crud/types\";\nimport type { HttpRequest, HttpResponse } from \"../http-types\";\nimport type { AdminRepoEntry, RepoRegistry } from \"./handlers\";\nimport { createAdminHandlers } from \"./handlers\";\nimport type { RelationalFieldMeta } from \"./renderer\";\nimport { type Middleware, MiniRouter } from \"./router\";\n\n// ---------------------------------------------------------------------------\n// Public option types\n// ---------------------------------------------------------------------------\n\n/**\n * Extracts the model type `T` from a `ConfiguredRepository`.\n * @internal\n */\ntype RepoModelType<TRepo> =\n TRepo extends ConfiguredRepository<\n RepositoryConfig<infer T, any, any, any, any, any, any, any, any, any>\n >\n ? T\n : never;\n\n/**\n * Configuration for a single repository in the admin server.\n *\n * @template TRepo - The `ConfiguredRepository` type; used to derive typed field names.\n *\n * If the repository was created with `createRepositoryConfig(schema)(config)`,\n * the `schema` field is optional — it is auto-detected from the repo.\n * Otherwise, pass `schema` explicitly.\n *\n * @example\n * ```ts\n * posts: {\n * repo: repos.posts,\n * fieldsConfig: {\n * title: [\"create\", \"mutable\", \"filterable\"],\n * content: [\"create\", \"mutable\"],\n * status: [\"create\", \"filterable\"],\n * },\n * allowDelete: true,\n * }\n * ```\n */\nexport interface AdminRepoConfig<\n TRepo extends ConfiguredRepository<any> = ConfiguredRepository<any>,\n> {\n /** The configured repository instance. Drives type inference for all other fields. */\n repo: TRepo;\n /**\n * Zod schema — optional when the repo was created with `createRepositoryConfig(schema)`.\n * Pass explicitly for repos created with the legacy `createRepositoryConfig<T>()` form.\n */\n schema?: z.ZodObject<any>;\n /** Firestore collection path (for display only) */\n path: string;\n /** Key used to identify documents (default: \"docId\") */\n documentKey?: string;\n /** Columns to display in the list view (default: all schema keys) */\n listColumns?: string[];\n /** Number of documents per page in the list view (default: 25) */\n pageSize?: number;\n /**\n * Per-field role configuration.\n * Each key is a model field (with autocomplete); the value is an array of roles.\n *\n * Roles:\n * - `\"create\"` — field is shown in the create form\n * - `\"mutable\"` — field is shown in the edit form\n * - `\"filterable\"` — field is shown in the filter bar\n *\n * If omitted, all schema fields are shown in all contexts.\n *\n * @example\n * ```ts\n * fieldsConfig: {\n * title: [\"create\", \"mutable\", \"filterable\"],\n * content: [\"create\", \"mutable\"],\n * status: [\"create\", \"filterable\"],\n * }\n * ```\n */\n fieldsConfig?: Partial<Record<FieldPath<RepoModelType<TRepo>>, readonly FieldRole[]>>;\n /**\n * Whether to show the delete button in the list view.\n * Default: false — delete is disabled unless explicitly set to true.\n */\n allowDelete?: boolean;\n /**\n * Relational action columns appended to the list table.\n * Each entry adds a dedicated button that navigates to the linked repository.\n *\n * - **type \"one\"** (e.g. `userId` on a post) → button links to the target\n * document edit page: `/{targetRepo}/{value}/edit`\n * - **type \"many\"** (e.g. `docId` on a user) → button links to the target\n * repo list filtered by value: `/{targetRepo}?fv_{targetKey}={value}`\n *\n * @example\n * ```ts\n * users: {\n * repo: repos.users,\n * relationalFields: [\n * { key: \"docId\", column: \"Posts\" }, // many → list of posts by this user\n * ]\n * }\n * posts: {\n * repo: repos.posts,\n * relationalFields: [\n * { key: \"userId\", column: \"Author\" }, // one → edit page of the user\n * ]\n * }\n * ```\n */\n relationalFields?: {\n key: keyof RepoModelType<TRepo> & string;\n column: string;\n }[];\n}\n\n/**\n * HTTP Basic Auth configuration.\n * The browser will show a native login dialog.\n */\nexport interface BasicAuthConfig {\n type: \"basic\";\n /** Realm displayed in the browser login dialog */\n realm?: string;\n username: string;\n password: string;\n}\n\n/**\n * Options for `createAdminServer`.\n *\n * Made generic so TypeScript can infer the model type of each repo entry\n * and provide autocomplete + type-checking on `fieldsConfig`.\n *\n * @template TRepos - Shape of the repos map (inferred automatically at the call site)\n */\nexport interface AdminServerOptions<\n TRepos extends Record<string, ConfiguredRepository<any>> = Record<\n string,\n ConfiguredRepository<any>\n >,\n> {\n /**\n * Base URL path of the function (e.g. \"/admin\").\n * Must match the path where the Firebase Function is mounted.\n * Default: \"/\"\n */\n basePath?: string;\n\n /**\n * Repository entries keyed by a display name.\n * TypeScript infers the model type from each `repo` field,\n * so `fieldsConfig` keys are typed to that model's field paths.\n *\n * @example\n * ```ts\n * repos: {\n * posts: {\n * repo: repos.posts,\n * fieldsConfig: {\n * title: [\"create\", \"mutable\", \"filterable\"],\n * content: [\"create\", \"mutable\"],\n * status: [\"create\", \"filterable\"],\n * },\n * },\n * }\n * ```\n */\n repos: { [K in keyof TRepos]: AdminRepoConfig<TRepos[K]> };\n\n /** Whether to parse URL-encoded bodies. Default: true. */\n parseBody?: boolean;\n\n /**\n * Authentication guard executed before every request.\n * - Pass a `BasicAuthConfig` to enable HTTP Basic Auth.\n * - Pass a `Middleware` function for custom auth logic.\n */\n auth?: BasicAuthConfig | Middleware;\n\n /**\n * Additional middleware functions executed after auth, before route handlers.\n */\n middleware?: Middleware[];\n\n /**\n * Options forwarded to `onRequest()` from `firebase-functions/v2/https`.\n * Stored on the returned handler as `.httpsOptions` for easy access.\n *\n * @example\n * ```ts\n * const handler = createAdminServer({ httpsOptions: { invoker: \"public\" }, ... });\n * export const admin = onRequest(handler.httpsOptions!, handler);\n * ```\n */\n httpsOptions?: Record<string, unknown>;\n}\n\n// ---------------------------------------------------------------------------\n// Body parser (replaces express.urlencoded in Firebase Functions context)\n// ---------------------------------------------------------------------------\n\n/** Eagerly reads the raw request body as a string */\nasync function readRawBody(req: HttpRequest): Promise<string> {\n if (typeof (req as any).rawBody === \"string\")\n return (req as any).rawBody as string;\n if (Buffer.isBuffer((req as any).rawBody))\n return ((req as any).rawBody as Buffer).toString(\"utf8\");\n // Firebase Functions v2 / Cloud Run: body may already be parsed\n return \"\";\n}\n\nfunction parseUrlEncoded(body: string): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {};\n if (!body) return result;\n for (const pair of body.split(\"&\")) {\n const idx = pair.indexOf(\"=\");\n if (idx === -1) continue;\n const key = decodeURIComponent(pair.slice(0, idx).replace(/\\+/g, \" \"));\n const val = decodeURIComponent(pair.slice(idx + 1).replace(/\\+/g, \" \"));\n const existing = result[key];\n if (existing === undefined) {\n result[key] = val;\n } else if (Array.isArray(existing)) {\n existing.push(val);\n } else {\n result[key] = [existing, val];\n }\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Creates an Express-compatible request handler for the admin ORM UI.\n * Generates a complete admin interface with dashboard, lists, and CRUD forms.\n *\n * @template TRepos - Shape of the repos map (inferred automatically)\n * @param options - Admin server configuration\n * @returns Express-compatible request handler for Firebase Functions\n *\n * @example\n * ```typescript\n * // Basic admin server\n * import { onRequest } from \"firebase-functions/https\";\n * import { createAdminServer } from \"@lpdjs/firestore-repo-service/servers/admin\";\n *\n * export const admin = onRequest(\n * createAdminServer({\n * basePath: \"/admin\",\n * repos: {\n * users: {\n * repo: repos.users,\n * path: \"users\",\n * },\n * posts: {\n * repo: repos.posts,\n * path: \"posts\",\n * },\n * },\n * })\n * );\n *\n * // With HTTP Basic Auth\n * export const admin = onRequest(\n * createAdminServer({\n * basePath: \"/admin\",\n * auth: {\n * type: \"basic\",\n * realm: \"Admin Area\",\n * username: \"admin\",\n * password: process.env.ADMIN_PASSWORD!,\n * },\n * repos: { ... },\n * })\n * );\n *\n * // With custom auth middleware\n * export const admin = onRequest(\n * createAdminServer({\n * auth: async (req, res, next) => {\n * const token = req.headers?.authorization?.replace(\"Bearer \", \"\");\n * if (!token || !(await verifyToken(token))) {\n * res.status(401).send(\"Unauthorized\");\n * return;\n * }\n * next();\n * },\n * repos: { ... },\n * })\n * );\n *\n * // Full configuration with all options\n * export const admin = onRequest(\n * createAdminServer({\n * basePath: \"/admin\",\n * parseBody: true, // Parse URL-encoded bodies\n * auth: { type: \"basic\", username: \"admin\", password: \"secret\" },\n * middleware: [loggingMiddleware], // Additional middleware\n * repos: {\n * posts: {\n * repo: repos.posts,\n * path: \"posts\",\n * documentKey: \"docId\", // Field used as document ID\n * listColumns: [\"title\", \"status\", \"createdAt\"], // Columns in list\n * pageSize: 25, // Items per page in list\n * fieldsConfig: {\n * title: [\"create\", \"mutable\", \"filterable\"],\n * content: [\"create\", \"mutable\"],\n * status: [\"create\", \"mutable\", \"filterable\"],\n * userId: [\"filterable\"],\n * },\n * allowDelete: true, // Enable delete button\n * relationalFields: [ // Relation navigation buttons\n * { key: \"userId\", column: \"Author\" }, // Link to user\n * { key: \"docId\", column: \"Comments\" }, // Link to comments list\n * ],\n * },\n * users: {\n * repo: repos.users,\n * path: \"users\",\n * fieldsConfig: {\n * name: [\"create\", \"mutable\"],\n * email: [\"create\", \"mutable\", \"filterable\"],\n * isActive: [\"mutable\", \"filterable\"],\n * },\n * allowDelete: false,\n * relationalFields: [\n * { key: \"docId\", column: \"Posts\" },\n * ],\n * },\n * },\n * })\n * );\n *\n * // Routes generated automatically:\n * // GET /admin/ → Dashboard (list of repos)\n * // GET /admin/:repo → Document list with pagination\n * // GET /admin/:repo/create → Create form\n * // POST /admin/:repo/create → Submit create\n * // GET /admin/:repo/:id/edit → Edit form\n * // POST /admin/:repo/:id/edit → Submit edit\n * // POST /admin/:repo/:id/delete → Delete document\n * ```\n */\nexport function createAdminServer<\n TRepos extends Record<string, ConfiguredRepository<any>>,\n>(\n options: AdminServerOptions<TRepos>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): ((req: any, res: any) => Promise<void>) & { httpsOptions?: Record<string, unknown> } {\n const {\n basePath = \"/\",\n repos,\n parseBody = true,\n auth,\n middleware: extraMiddleware = [],\n httpsOptions,\n } = options;\n\n // Normalise basePath: no trailing slash\n const base = basePath === \"/\" ? \"\" : basePath.replace(/\\/$/, \"\");\n\n // Build the registry\n const registry: RepoRegistry = {};\n for (const [name, cfg] of Object.entries(repos)) {\n // Schema resolution: explicit cfg.schema > embedded in repo (createRepositoryConfig(schema))\n const resolvedSchema = cfg.schema ?? (cfg.repo as any).schema ?? null;\n if (!resolvedSchema) {\n throw new Error(\n `[createAdminServer] Repository \"${name}\" has no Zod schema. ` +\n `Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`,\n );\n }\n // Resolve fieldsConfig → separate arrays for runtime\n let filterableFields: string[] | undefined;\n let mutableFields: string[] | undefined;\n let createFields: string[] | undefined;\n if (cfg.fieldsConfig) {\n const fc = cfg.fieldsConfig as Record<string, readonly string[]>;\n filterableFields = [];\n mutableFields = [];\n createFields = [];\n for (const [field, roles] of Object.entries(fc)) {\n for (const role of roles) {\n if (role === \"filterable\") filterableFields.push(field);\n else if (role === \"mutable\") mutableFields.push(field);\n else if (role === \"create\") createFields.push(field);\n }\n }\n if (filterableFields.length === 0) filterableFields = undefined;\n if (mutableFields.length === 0) mutableFields = undefined;\n if (createFields.length === 0) createFields = undefined;\n }\n\n // For collection-group repos, ensure parentKeys are included in createFields\n // so the form/validation allows the user to provide them.\n const parentKeys = (() => {\n const pk = (cfg.repo as any)._parentKeys as string[] | undefined;\n return pk && pk.length > 0 ? pk : undefined;\n })();\n if (parentKeys && createFields) {\n for (const pk of parentKeys) {\n if (!createFields.includes(pk)) createFields.push(pk);\n }\n }\n\n const entry: AdminRepoEntry = {\n name,\n path: cfg.path,\n repo: cfg.repo,\n schema: resolvedSchema,\n documentKey: cfg.documentKey ?? \"docId\",\n pathKey: (cfg.repo as any)._pathKey ?? undefined,\n isGroup: !!(cfg.repo as any)._isGroup,\n parentKeys,\n createdKey: (cfg.repo as any)._createdKey ?? undefined,\n listColumns: cfg.listColumns,\n pageSize: cfg.pageSize,\n filterableFields,\n mutableFields,\n createFields,\n allowDelete: cfg.allowDelete ?? false,\n relationalMeta: (() => {\n if (!cfg.relationalFields || cfg.relationalFields.length === 0)\n return undefined;\n const repoRelKeys = (cfg.repo as any).relationalKeys ?? {};\n const meta: RelationalFieldMeta[] = [];\n for (const entry of cfg.relationalFields) {\n const rel = repoRelKeys[entry.key];\n if (rel) {\n meta.push({\n key: entry.key,\n column: entry.column,\n targetRepo: String(rel.repo),\n targetKey: String(rel.key),\n type: rel.type as \"one\" | \"many\",\n });\n }\n }\n return meta.length > 0 ? meta : undefined;\n })(),\n };\n registry[name] = entry;\n }\n\n const handlers = createAdminHandlers(registry, base);\n\n // ── Router ─────────────────────────────────────────────────────────────\n const router = new MiniRouter();\n\n // ── 1. Body-parsing middleware ──────────────────────────────────────────\n if (parseBody) {\n router.use(async (req, _res, next) => {\n const r = req as unknown as HttpRequest;\n const contentType = String(r.headers?.[\"content-type\"] ?? \"\");\n if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n const raw = await readRawBody(r);\n (req as any).body = parseUrlEncoded(raw);\n } else if (\n contentType.includes(\"application/json\") &&\n typeof r.body === \"string\"\n ) {\n try {\n (req as any).body = JSON.parse(r.body as string);\n } catch {\n /* keep as string */\n }\n }\n await next();\n });\n }\n\n // ── 2. Auth middleware ──────────────────────────────────────────────────\n if (auth) {\n if (typeof auth === \"function\") {\n // Custom middleware\n router.use(auth);\n } else {\n // HTTP Basic Auth\n const realm = auth.realm ?? \"Admin\";\n const expected =\n \"Basic \" +\n Buffer.from(`${auth.username}:${auth.password}`).toString(\"base64\");\n router.use((req, res, next) => {\n const authorization = (req as any).headers?.[\"authorization\"] ?? \"\";\n if (authorization !== expected) {\n res\n .status(401)\n .set(\"WWW-Authenticate\", `Basic realm=\"${realm}\"`)\n .set(\"Content-Type\", \"text/plain\")\n .send(\"Unauthorized\");\n return;\n }\n next();\n });\n }\n }\n\n // ── 3. Extra user middleware ────────────────────────────────────────────\n for (const mw of extraMiddleware) {\n router.use(mw);\n }\n\n // ── 4. Routes ─────────────────────────────────────────────────────────────\n router.get(`${base}/`, handlers.handleDashboard);\n router.get(`${base}`, handlers.handleDashboard);\n\n router.get(`${base}/:repoName`, handlers.handleList);\n\n router.get(`${base}/:repoName/create`, handlers.handleCreateForm);\n router.post(`${base}/:repoName/create`, handlers.handleCreateSubmit as any);\n\n router.get(`${base}/:repoName/:id/edit`, handlers.handleEditForm as any);\n router.post(`${base}/:repoName/:id/edit`, handlers.handleEditSubmit as any);\n\n router.post(`${base}/:repoName/:id/delete`, handlers.handleDelete as any);\n\n // ── Request handler ─────────────────────────────────────────────────────\n const handler = async (req: HttpRequest, res: HttpResponse): Promise<void> => {\n await router.handle(req as any, res as any);\n };\n if (httpsOptions) (handler as any).httpsOptions = httpsOptions;\n return handler as ((req: any, res: any) => Promise<void>) & { httpsOptions?: Record<string, unknown> };\n}\n\n// Re-exports for convenience\nexport type { AdminRepoEntry, RepoRegistry } from \"./handlers\";\nexport { MiniRouter } from \"./router\";\nexport type { Middleware, RouteHandler } from \"./router\";\n"]}
1
+ {"version":3,"sources":["../../../src/shared/zod-compat.ts","../../../src/servers/admin/form-gen.ts","../../../src/servers/admin/components/cell-value.tsx","../../../src/servers/admin/components/client-script.raw.js","../../../src/servers/admin/components/client-script.tsx","../../../src/servers/admin/components/shell.tsx","../../../src/servers/admin/components/dashboard.tsx","../../../src/servers/admin/components/filter-bar.tsx","../../../src/servers/admin/components/form.tsx","../../../src/servers/admin/components/list.tsx","../../../src/servers/admin/renderer.ts","../../../src/servers/admin/handlers.ts","../../../src/servers/admin/router.ts","../../../src/servers/admin/index.ts"],"names":["TYPE_MAP","getTypeName","schema","s","v4Type","v3Type","getInnerType","getArrayElementType","getDefaultValue","v","getShape","getEnumValues","getNativeEnumValues","getLiteralValue","getStringChecks","kinds","v4Checks","c","v3Checks","toLabel","name","unwrap","inner","required","nullable","defaultValue","tn","zodToFields","namePrefix","shape","fieldName","fieldSchema","zodFieldToDescriptor","rawName","label","checks","isEmail","isUrl","values","enumObj","value","nested","elSchema","elInner","elTn","arrayElementType","arrayElementOptions","arrayElementFields","renderField","field","depth","indent","id","nameAttr","requiredAttr","isNullValue","defaultStr","nullToggle","input","sel3","e","o","renderArrayField","subFields","f","isObject","items","itemsHtml","item","renderObjectItem","renderPrimitiveItem","templateHtml","strVal","inputHtml","obj","val","renderForm","fields","action","method","submitLabel","fieldsHtml","CellDate","jsx","CellValue","jsxs","i","entries","k","Fragment","str","client_script_raw_default","ClientScript","renderHtml","element","renderToString","PageShell","opts","children","title","breadcrumb","flash","basePath","renderDashboardJsx","repos","r","OPS_TEXT","OPS_NUMERIC","OPS_ARRAY","opsForType","zodType","FilterValueInput","col","active","isAny","FilterBar","columnMeta","activeFilters","activeMap","hasActive","filterable","ops","currentOp","renderFormPageJsx","repoName","formHtml","mode","docId","crumbs","baseParams","filters","sort","pageSize","p","paginationHref","cursor","dir","sortHref","current","pageSizeHref","newPs","renderListJsx","docs","columns","pagination","allowDelete","relationalMeta","sortState","currentPageSize","listUrl","createUrl","ps","isSorted","arrow","m","doc","rowIdx","editUrl","deleteUrl","ci","mi","rawVal","href","renderDashboard","renderList","renderFormPage","_idChars","generateFirestoreId","extractPathArgs","pathKey","fullPath","segments","args","fetchDocById","entry","docKey","getMethod","sendHtml","res","html","status","redirect","to","parseFormBody","raw","result","key","zodField","resolveTypeName","subRaw","hasDotKeys","innerSchema","itn","toDatetimeLocal","date","d","pad","n","prefillFromDoc","prefix","fullKey","innerTn","dtLocal","applyPrefill","prefilled","parseFilters","query","validFields","validOps","opRaw","op","filtersToWhere","coerce","arr","buildColumnMeta","fullName","subShape","resolveZodAtPath","path","parts","part","getMutableSchema","topLevel","dotGroups","dot","parent","child","picked","z","getLinkBase","req","staticBasePath","base","project","region","target","service","host","createAdminHandlers","registry","lb","cursorStr","sortField","sortDir","psRaw","allColumns","filterableColumns","out","resolved","whereFilters","cursorSnapshot","colRef","nextCursorId","prevCursorId","createSchema","actionUrl","rawBody","parsed","validation","errorMsg","data","missingKeys","parentIds","err","createSchema2","mutableSchema","pathArgs","mutableSchema2","compilePath","paramNames","src","_match","extractPath","idx","MiniRouter","_req","middleware","handler","pattern","matchedRoute","params","route","enrichedReq","finalHandler","index","next","mw","readRawBody","parseUrlEncoded","body","pair","existing","createAdminServer","options","parseBody","auth","extraMiddleware","httpsOptions","cfg","resolvedSchema","filterableFields","mutableFields","createFields","fc","roles","role","parentKeys","pk","repoRelKeys","meta","rel","handlers","router","_res","contentType","realm","expected"],"mappings":"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AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACKS,CAAA,CAHF,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","file":"index.cjs","sourcesContent":["/**\n * Zod introspection utilities — compatible with Zod 4.\n *\n * Centralizes all internal `_zod.def` accesses so the rest of the codebase\n * never touches Zod internals directly. If a future Zod version changes\n * the internal layout, only this file needs updating.\n */\n\nimport type { z } from \"zod\";\n\n// ---------------------------------------------------------------------------\n// Type-name resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Canonical Zod type names used in the codebase.\n * These match the **Zod 3** naming convention (e.g. \"ZodString\") that the\n * form-gen / admin handlers already rely on, so we don't need to rewrite\n * every `case \"ZodString\":` branch.\n */\ntype ZodTypeName =\n | \"ZodString\"\n | \"ZodNumber\"\n | \"ZodBigInt\"\n | \"ZodBoolean\"\n | \"ZodDate\"\n | \"ZodEnum\"\n | \"ZodNativeEnum\"\n | \"ZodLiteral\"\n | \"ZodObject\"\n | \"ZodArray\"\n | \"ZodOptional\"\n | \"ZodNullable\"\n | \"ZodDefault\"\n | \"ZodCoerce\"\n | \"ZodUnion\"\n | \"ZodUndefined\"\n | \"ZodUnknown\"\n | \"ZodAny\"\n | \"ZodRecord\"\n | string;\n\n/**\n * Map from Zod 4 `_zod.def.type` (lowercase) → Zod 3 `_def.typeName` format.\n * Any key not in this map is capitalised as `Zod${Capitalised}`.\n */\nconst TYPE_MAP: Record<string, ZodTypeName> = {\n string: \"ZodString\",\n number: \"ZodNumber\",\n bigint: \"ZodBigInt\",\n boolean: \"ZodBoolean\",\n date: \"ZodDate\",\n enum: \"ZodEnum\",\n nativeEnum: \"ZodNativeEnum\",\n literal: \"ZodLiteral\",\n object: \"ZodObject\",\n array: \"ZodArray\",\n optional: \"ZodOptional\",\n nullable: \"ZodNullable\",\n default: \"ZodDefault\",\n coerce: \"ZodCoerce\",\n union: \"ZodUnion\",\n undefined: \"ZodUndefined\",\n unknown: \"ZodUnknown\",\n any: \"ZodAny\",\n record: \"ZodRecord\",\n};\n\n/**\n * Get the canonical type name of a Zod schema.\n *\n * Works with both Zod 3 (`_def.typeName`) and Zod 4 (`_zod.def.type`).\n * Returns names in Zod-3 style (\"ZodString\", \"ZodObject\" …) for\n * backward-compatible switch/case usage.\n */\nexport function getTypeName(schema: z.ZodType): ZodTypeName {\n const s = schema as any;\n\n // Zod 4 path\n const v4Type: string | undefined = s._zod?.def?.type;\n if (v4Type)\n return (\n TYPE_MAP[v4Type] ??\n `Zod${v4Type.charAt(0).toUpperCase()}${v4Type.slice(1)}`\n );\n\n // Zod 3 fallback\n const v3Type: string | undefined = s._def?.typeName;\n if (v3Type) return v3Type;\n\n return \"\";\n}\n\n// ---------------------------------------------------------------------------\n// Unwrapping wrappers (Optional / Nullable / Default)\n// ---------------------------------------------------------------------------\n\n/**\n * Get the inner schema from a wrapper type (Optional / Nullable / Default).\n */\nexport function getInnerType(schema: z.ZodType): z.ZodType | undefined {\n const s = schema as any;\n\n // Zod 4: _zod.def.innerType\n if (s._zod?.def?.innerType) return s._zod.def.innerType;\n\n // Zod 3 compat: _def.innerType\n if (s._def?.innerType) return s._def.innerType;\n\n return undefined;\n}\n\n/**\n * Get the **element schema** from a `ZodArray`.\n * Returns `undefined` for non-array schemas.\n */\nexport function getArrayElementType(\n schema: z.ZodType,\n): z.ZodType | undefined {\n const s = schema as any;\n\n // Zod 4: _zod.def.element\n if (s._zod?.def?.element) return s._zod.def.element;\n\n // Zod 3: _def.type (ZodArray stores element schema in _def.type)\n if (s._def?.type) return s._def.type;\n\n return undefined;\n}\n\n/**\n * Returns the list of **required** (non-optional) top-level keys of a ZodObject.\n * A key is required when its schema is NOT wrapped in ZodOptional.\n * ZodNullable / ZodDefault fields are still considered required — they must be present.\n */\nexport function getRequiredSchemaKeys(schema: z.ZodObject<any>): string[] {\n const required: string[] = [];\n for (const [key, fieldSchema] of Object.entries(schema.shape)) {\n const typeName = getTypeName(fieldSchema as z.ZodType);\n if (typeName !== \"ZodOptional\") {\n required.push(key);\n }\n }\n return required;\n}\n\n/**\n * Get the default value for a ZodDefault schema.\n * In Zod 3 this was `_def.defaultValue()` (function). In Zod 4 it's a direct value.\n */\nexport function getDefaultValue(schema: z.ZodType): unknown {\n const s = schema as any;\n\n // Zod 4\n if (s._zod?.def?.defaultValue !== undefined) return s._zod.def.defaultValue;\n\n // Zod 3 compat\n const v = s._def?.defaultValue;\n if (typeof v === \"function\") return v();\n return v;\n}\n\n// ---------------------------------------------------------------------------\n// Object shape\n// ---------------------------------------------------------------------------\n\n/**\n * Get the shape of a ZodObject schema (Record<string, ZodType>).\n * Handles both Zod 3 (`_def.shape()` function) and Zod 4 (`.shape` property).\n */\nexport function getShape(schema: z.ZodType): Record<string, z.ZodType> {\n const s = schema as any;\n\n // Direct `.shape` property (Zod 3 & 4 for ZodObject instances)\n if (s.shape && typeof s.shape === \"object\") return s.shape;\n\n // Zod 4: _zod.def.shape\n if (s._zod?.def?.shape && typeof s._zod.def.shape === \"object\")\n return s._zod.def.shape;\n\n // Zod 3 fallback: _def.shape() or _def.shape\n if (s._def?.shape) {\n return typeof s._def.shape === \"function\" ? s._def.shape() : s._def.shape;\n }\n\n return {};\n}\n\n// ---------------------------------------------------------------------------\n// Enum / Literal values\n// ---------------------------------------------------------------------------\n\n/**\n * Get the values of a ZodEnum schema as a string[].\n */\nexport function getEnumValues(schema: z.ZodType): string[] {\n const s = schema as any;\n\n // Zod 4: `.options` or `_zod.def.entries`\n if (Array.isArray(s.options)) return s.options;\n if (s._zod?.def?.entries)\n return Object.values(s._zod.def.entries) as string[];\n\n // Zod 3: `_def.values`\n if (Array.isArray(s._def?.values)) return s._def.values;\n\n return [];\n}\n\n/**\n * Get the value object of a ZodNativeEnum schema.\n */\nexport function getNativeEnumValues(\n schema: z.ZodType,\n): Record<string, unknown> {\n const s = schema as any;\n\n // Zod 4: `_zod.def.entries` or `.enum`\n if (s._zod?.def?.entries) return s._zod.def.entries;\n if (s.enum && typeof s.enum === \"object\") return s.enum;\n\n // Zod 3: `_def.values`\n if (s._def?.values && typeof s._def.values === \"object\") return s._def.values;\n\n return {};\n}\n\n/**\n * Get the value of a ZodLiteral schema.\n */\nexport function getLiteralValue(schema: z.ZodType): unknown {\n const s = schema as any;\n\n // Zod 4: `_zod.def.values[0]`\n if (Array.isArray(s._zod?.def?.values)) return s._zod.def.values[0];\n\n // Zod 3: `_def.value`\n return s._def?.value;\n}\n\n// ---------------------------------------------------------------------------\n// String checks\n// ---------------------------------------------------------------------------\n\n/**\n * Get relevant \"check kinds\" from a ZodString schema.\n * Returns an array of kind strings: \"email\", \"url\", etc.\n */\nexport function getStringChecks(schema: z.ZodType): string[] {\n const s = schema as any;\n const kinds: string[] = [];\n\n // Zod 4: checks with `.format` field\n const v4Checks: any[] | undefined = s._zod?.def?.checks;\n if (Array.isArray(v4Checks)) {\n for (const c of v4Checks) {\n if (c.format) kinds.push(c.format);\n }\n if (kinds.length > 0) return kinds;\n }\n\n // Zod 3: _def.checks with `.kind` field\n const v3Checks: any[] | undefined = s._def?.checks;\n if (Array.isArray(v3Checks)) {\n for (const c of v3Checks) {\n if (c.kind) kinds.push(c.kind);\n }\n }\n\n return kinds;\n}\n","/**\n * Zod-to-HTML form generator.\n * Inspects a Zod schema's `_def` to produce typed HTML `<input>` / `<select>`\n * elements — no extra dependencies needed.\n *\n * Supported Zod types:\n * ZodString, ZodNumber, ZodBoolean, ZodDate, ZodEnum,\n * ZodOptional, ZodNullable, ZodDefault, ZodObject, ZodArray, ZodLiteral\n *\n * For ZodObject fields, nested sections are rendered with indentation.\n * For ZodArray and unknown types, a `<textarea>` with JSON hint is used.\n *\n * @example\n * ```typescript\n * import { zodToFields, renderForm } from \"@lpdjs/firestore-repo-service/servers/admin\";\n *\n * // Convert Zod schema to field descriptors\n * const schema = z.object({\n * name: z.string(),\n * email: z.string().email(),\n * age: z.number().optional(),\n * role: z.enum([\"admin\", \"user\"]),\n * isActive: z.boolean().default(true),\n * address: z.object({\n * street: z.string(),\n * city: z.string(),\n * }),\n * });\n *\n * const fields = zodToFields(schema);\n * // Returns:\n * // [\n * // { name: \"name\", type: \"text\", required: true, ... },\n * // { name: \"email\", type: \"text\", required: true, hint: \"email\", ... },\n * // { name: \"age\", type: \"number\", required: false, ... },\n * // { name: \"role\", type: \"select\", options: [\"admin\", \"user\"], ... },\n * // { name: \"isActive\", type: \"checkbox\", defaultValue: true, ... },\n * // { name: \"address\", nested: [...], ... },\n * // ]\n *\n * // Render form HTML\n * const html = renderForm(fields, \"create\", {\n * name: \"John\",\n * email: \"john@example.com\",\n * });\n *\n * // Render single field\n * const fieldHtml = renderField(fields[0], { name: \"Jane\" });\n * ```\n */\n\nimport type { z } from \"zod\";\nimport {\n getArrayElementType,\n getDefaultValue,\n getEnumValues,\n getInnerType,\n getLiteralValue,\n getNativeEnumValues,\n getShape,\n getStringChecks,\n getTypeName,\n} from \"../../shared/zod-compat\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface FieldDescriptor {\n name: string;\n label: string;\n type:\n | \"text\"\n | \"number\"\n | \"checkbox\"\n | \"datetime-local\"\n | \"select\"\n | \"textarea\";\n required: boolean;\n nullable: boolean;\n options?: string[]; // for select\n defaultValue?: unknown;\n nested?: FieldDescriptor[]; // for objects\n hint?: string;\n /** For array fields: the element input type */\n arrayElementType?:\n | \"text\"\n | \"number\"\n | \"checkbox\"\n | \"select\"\n | \"datetime-local\"\n | \"object\";\n /** For enum arrays: the allowed values */\n arrayElementOptions?: string[];\n /** For object arrays: the field descriptors for one element */\n arrayElementFields?: FieldDescriptor[];\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Convert camelCase / snake_case to \"Human Label\" */\nfunction toLabel(name: string): string {\n return name\n .replace(/([A-Z])/g, \" $1\")\n .replace(/_/g, \" \")\n .replace(/^\\s/, \"\")\n .replace(/^./, (c) => c.toUpperCase());\n}\n\n/** Unwrap ZodOptional / ZodNullable / ZodDefault to the inner schema */\nfunction unwrap(schema: z.ZodType): {\n inner: z.ZodType;\n required: boolean;\n nullable: boolean;\n defaultValue: unknown;\n} {\n let inner: z.ZodType = schema;\n let required = true;\n let nullable = false;\n let defaultValue: unknown = undefined;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const tn = getTypeName(inner);\n if (tn === \"ZodOptional\") {\n required = false;\n inner = getInnerType(inner)!;\n } else if (tn === \"ZodNullable\") {\n required = false;\n nullable = true;\n inner = getInnerType(inner)!;\n } else if (tn === \"ZodDefault\") {\n required = false;\n defaultValue = getDefaultValue(inner);\n inner = getInnerType(inner)!;\n } else {\n break;\n }\n }\n\n return { inner, required, nullable, defaultValue };\n}\n\n// ---------------------------------------------------------------------------\n// Core introspection\n// ---------------------------------------------------------------------------\n\nexport function zodToFields(\n schema: z.ZodType,\n namePrefix = \"\",\n): FieldDescriptor[] {\n const tn = getTypeName(schema);\n\n if (tn === \"ZodObject\") {\n const shape: Record<string, z.ZodType> = getShape(schema);\n return Object.entries(shape).map(([fieldName, fieldSchema]) =>\n zodFieldToDescriptor(\n namePrefix ? `${namePrefix}.${fieldName}` : fieldName,\n fieldName,\n fieldSchema,\n ),\n );\n }\n\n // If the root schema is not an object, treat it as a single field\n return [\n zodFieldToDescriptor(namePrefix || \"value\", namePrefix || \"value\", schema),\n ];\n}\n\nfunction zodFieldToDescriptor(\n name: string,\n rawName: string,\n schema: z.ZodType,\n): FieldDescriptor {\n const { inner, required, nullable, defaultValue } = unwrap(schema);\n const tn = getTypeName(inner);\n const label = toLabel(rawName.split(\".\").pop() ?? rawName);\n\n switch (tn) {\n case \"ZodString\": {\n const checks = getStringChecks(inner);\n const isEmail = checks.includes(\"email\");\n const isUrl = checks.includes(\"url\");\n return {\n name,\n label,\n type: \"text\",\n required,\n nullable,\n defaultValue,\n hint: isEmail ? \"email\" : isUrl ? \"url\" : undefined,\n };\n }\n\n case \"ZodNumber\":\n case \"ZodBigInt\":\n return { name, label, type: \"number\", required, nullable, defaultValue };\n\n case \"ZodBoolean\":\n return {\n name,\n label,\n type: \"checkbox\",\n required,\n nullable,\n defaultValue,\n };\n\n case \"ZodDate\":\n case \"ZodCoerce\":\n return {\n name,\n label,\n type: \"datetime-local\",\n required,\n nullable,\n defaultValue,\n };\n\n case \"ZodEnum\": {\n const values = getEnumValues(inner);\n return {\n name,\n label,\n type: \"select\",\n required,\n nullable,\n defaultValue,\n options: values,\n };\n }\n\n case \"ZodNativeEnum\": {\n const enumObj = getNativeEnumValues(inner);\n const values = Object.values(enumObj).filter(\n (v) => typeof v === \"string\",\n ) as string[];\n return {\n name,\n label,\n type: \"select\",\n required,\n nullable,\n defaultValue,\n options: values,\n };\n }\n\n case \"ZodLiteral\": {\n const value = String(getLiteralValue(inner) ?? \"\");\n return {\n name,\n label,\n type: \"select\",\n required,\n nullable,\n defaultValue,\n options: [value],\n };\n }\n\n case \"ZodObject\": {\n const nested = zodToFields(inner, name);\n return {\n name,\n label,\n type: \"textarea\",\n required,\n nullable,\n defaultValue,\n nested,\n hint: \"JSON object\",\n };\n }\n\n case \"ZodArray\": {\n const elSchema = getArrayElementType(inner);\n if (!elSchema) {\n return {\n name,\n label,\n type: \"textarea\",\n required,\n nullable,\n defaultValue,\n hint: \"JSON array\",\n };\n }\n const { inner: elInner } = unwrap(elSchema);\n const elTn = getTypeName(elInner);\n\n let arrayElementType: FieldDescriptor[\"arrayElementType\"];\n let arrayElementOptions: string[] | undefined;\n let arrayElementFields: FieldDescriptor[] | undefined;\n\n switch (elTn) {\n case \"ZodString\":\n arrayElementType = \"text\";\n break;\n case \"ZodNumber\":\n case \"ZodBigInt\":\n arrayElementType = \"number\";\n break;\n case \"ZodBoolean\":\n arrayElementType = \"checkbox\";\n break;\n case \"ZodDate\":\n arrayElementType = \"datetime-local\";\n break;\n case \"ZodEnum\":\n arrayElementType = \"select\";\n arrayElementOptions = getEnumValues(elInner);\n break;\n case \"ZodNativeEnum\":\n arrayElementType = \"select\";\n arrayElementOptions = Object.values(\n getNativeEnumValues(elInner),\n ).filter((v) => typeof v === \"string\") as string[];\n break;\n case \"ZodObject\":\n arrayElementType = \"object\";\n arrayElementFields = zodToFields(elInner);\n break;\n default:\n // Unknown element type → JSON textarea fallback\n return {\n name,\n label,\n type: \"textarea\",\n required,\n nullable,\n defaultValue,\n hint: \"JSON array\",\n };\n }\n\n return {\n name,\n label,\n type: \"textarea\",\n required,\n nullable,\n defaultValue,\n arrayElementType,\n arrayElementOptions,\n arrayElementFields,\n };\n }\n\n default:\n return {\n name,\n label,\n type: \"textarea\",\n required,\n nullable,\n defaultValue,\n hint: \"JSON\",\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// HTML generation — DaisyUI + Tailwind classes\n// ---------------------------------------------------------------------------\n\nexport function renderField(field: FieldDescriptor, depth = 0): string {\n const indent = depth > 0 ? `ml-${depth * 4}` : \"\";\n const id = `field_${field.name.replace(/\\./g, \"__\")}`;\n const nameAttr = field.name;\n const requiredAttr = field.required ? \" required\" : \"\";\n // \"__null__\" is the sentinel value used when a nullable field is set to null\n const isNullValue = field.defaultValue === \"__null__\";\n const defaultStr =\n !isNullValue && field.defaultValue != null\n ? String(field.defaultValue)\n : \"\";\n\n // Null toggle — rendered inline to the right of the input for nullable non-checkbox fields\n const nullToggle =\n field.nullable && field.type !== \"checkbox\"\n ? `<span class=\"flex items-center gap-1 shrink-0\">\n <input type=\"hidden\" id=\"${id}__isnull\" name=\"${nameAttr}__isnull\" value=\"${isNullValue ? \"1\" : \"\"}\">\n <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\">\n <input type=\"checkbox\" class=\"checkbox checkbox-xs\" ${isNullValue ? \"checked\" : \"\"}\n onchange=\"(function(cb){\n var inp = document.getElementById('${id}');\n var h = document.getElementById('${id}__isnull');\n if (cb.checked) { inp.disabled=true; inp.style.opacity='0.35'; h.value='1'; }\n else { inp.disabled=false; inp.style.opacity=''; h.value=''; }\n })(this)\">\n <span>null</span>\n </label>\n </span>`\n : \"\";\n\n let input: string;\n\n switch (field.type) {\n case \"checkbox\":\n // Nullable boolean → 3-state select (null / true / false)\n if (field.nullable) {\n const sel3 = isNullValue\n ? \"__null__\"\n : defaultStr === \"true\"\n ? \"true\"\n : defaultStr === \"false\"\n ? \"false\"\n : \"__null__\";\n return `\n <div class=\"form-control mb-3 ${indent}\">\n <label for=\"${id}\" class=\"label pb-1\">\n <span class=\"label-text font-medium\">\n ${e(field.label)}\n <span class=\"text-base-content/40 text-xs ml-1\">(nullable)</span>\n </span>\n </label>\n <select id=\"${id}\" name=\"${nameAttr}\" class=\"select select-bordered select-sm w-full\">\n <option value=\"__null__\"${sel3 === \"__null__\" ? \" selected\" : \"\"}>— null —</option>\n <option value=\"true\"${sel3 === \"true\" ? \" selected\" : \"\"}>✓ true</option>\n <option value=\"false\"${sel3 === \"false\" ? \" selected\" : \"\"}>✗ false</option>\n </select>\n </div>`;\n }\n return `\n <div class=\"form-control ${indent}\">\n <label class=\"label cursor-pointer justify-start gap-3\">\n <input type=\"checkbox\" id=\"${id}\" name=\"${nameAttr}\" value=\"true\"${\n defaultStr === \"true\" ? \" checked\" : \"\"\n } class=\"checkbox checkbox-primary checkbox-sm\">\n <span class=\"label-text font-medium\">\n ${e(field.label)}${field.required ? ` <span class=\"text-error\">*</span>` : \"\"}\n </span>\n </label>\n </div>`;\n\n case \"select\":\n input = `<select id=\"${id}\" name=\"${nameAttr}\"${requiredAttr}${isNullValue ? ' disabled style=\"opacity:0.35\"' : \"\"} class=\"select select-bordered select-sm w-full\">\n ${field.required && !field.nullable ? \"\" : `<option value=\"\">— optional —</option>`}\n ${(field.options ?? []).map((o) => `<option value=\"${e(o)}\"${defaultStr === o ? \" selected\" : \"\"}>${e(o)}</option>`).join(\"\\n \")}\n </select>`;\n break;\n\n case \"textarea\":\n if (field.arrayElementType) {\n return renderArrayField(field, depth);\n }\n if (field.nested && field.nested.length > 0) {\n const subFields = field.nested\n .map((f) => renderField(f, depth + 1))\n .join(\"\\n\");\n return `\n <fieldset class=\"fieldset border border-base-300 rounded-box p-3 mb-3 ${indent}\">\n <legend class=\"fieldset-legend text-xs font-semibold text-base-content/60 px-1\">\n ${e(field.label)}${field.required ? ` <span class=\"text-error\">*</span>` : \"\"}\n </legend>\n ${subFields}\n </fieldset>`;\n }\n input = `<textarea id=\"${id}\" name=\"${nameAttr}\"${requiredAttr} rows=\"3\"${isNullValue ? ' disabled style=\"opacity:0.35\"' : \"\"}\n data-json\n class=\"textarea textarea-bordered textarea-sm w-full font-mono text-xs\"\n placeholder=\"${e(field.hint ?? \"JSON\")}\">${e(defaultStr)}</textarea>`;\n break;\n\n default:\n input = `<input type=\"${field.type}\" id=\"${id}\" name=\"${nameAttr}\"${requiredAttr}${isNullValue ? ' disabled style=\"opacity:0.35\"' : \"\"}\n value=\"${e(defaultStr)}\"\n class=\"input input-bordered input-sm w-full\"${\n field.hint === \"email\"\n ? ' autocomplete=\"email\"'\n : field.hint === \"url\"\n ? ' autocomplete=\"url\"'\n : \"\"\n }>`;\n }\n\n return `\n <div class=\"form-control mb-3 ${indent}\">\n <label for=\"${id}\" class=\"label pb-1\">\n <span class=\"label-text font-medium\">\n ${e(field.label)}${field.required ? ` <span class=\"text-error\">*</span>` : \"\"}\n ${field.hint ? `<span class=\"text-base-content/40 text-xs ml-1\">(${e(field.hint)})</span>` : \"\"}\n </span>\n </label>\n <div class=\"flex items-center gap-2\">\n <div class=\"flex-1 min-w-0\">${input}</div>\n ${nullToggle}\n </div>\n </div>`;\n}\n\n/** Minimal HTML escape */\nfunction e(s: string): string {\n return s\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\n// ---------------------------------------------------------------------------\n// Array field rendering\n// ---------------------------------------------------------------------------\n\nfunction renderArrayField(field: FieldDescriptor, depth: number): string {\n const indent = depth > 0 ? `ml-${depth * 4}` : \"\";\n const id = `field_${field.name.replace(/\\./g, \"__\")}`;\n const isNullValue = field.defaultValue === \"__null__\";\n const isObject = field.arrayElementType === \"object\";\n\n // Parse existing value (JSON string → array)\n let items: unknown[] = [];\n if (\n field.defaultValue != null &&\n field.defaultValue !== \"\" &&\n field.defaultValue !== \"__null__\"\n ) {\n try {\n items = JSON.parse(String(field.defaultValue));\n } catch {\n /* ignore */\n }\n }\n if (!Array.isArray(items)) items = [];\n\n const itemsHtml = isObject\n ? items\n .map((item) =>\n renderObjectItem(field, (item as Record<string, unknown>) ?? {}),\n )\n .join(\"\\n\")\n : items.map((item) => renderPrimitiveItem(field, item)).join(\"\\n\");\n\n const templateHtml = isObject\n ? renderObjectItem(field, {})\n : renderPrimitiveItem(field, \"\");\n\n // Null toggle for nullable array fields\n const nullToggle =\n field.nullable\n ? `<span class=\"flex items-center gap-1 mt-2\">\n <input type=\"hidden\" id=\"${id}__isnull\" name=\"${e(field.name)}__isnull\" value=\"${isNullValue ? \"1\" : \"\"}\">\n <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\">\n <input type=\"checkbox\" class=\"checkbox checkbox-xs\" ${isNullValue ? \"checked\" : \"\"}\n onchange=\"(function(cb){\n var fs = cb.closest('[data-frs-array]');\n var h = document.getElementById('${id}__isnull');\n var hidden = document.getElementById('${id}');\n if (cb.checked) { fs.querySelector('[data-frs-array-items]').style.opacity='0.35'; h.value='1'; hidden.disabled=true; }\n else { fs.querySelector('[data-frs-array-items]').style.opacity=''; h.value=''; hidden.disabled=false; }\n })(this)\">\n <span>null</span>\n </label>\n </span>`\n : \"\";\n\n return `\n <fieldset class=\"fieldset border border-base-300 rounded-box p-3 mb-3 ${indent}\"\n data-frs-array=\"${e(field.name)}\" data-frs-array-type=\"${e(field.arrayElementType ?? \"text\")}\">\n <legend class=\"fieldset-legend text-xs font-semibold text-base-content/60 px-1\">\n ${e(field.label)}${field.required ? ` <span class=\"text-error\">*</span>` : \"\"}\n </legend>\n <input type=\"hidden\" id=\"${id}\" name=\"${e(field.name)}\" value=\"${e(JSON.stringify(items))}\"${isNullValue ? \" disabled\" : \"\"}>\n <div data-frs-array-items${isNullValue ? ' style=\"opacity:0.35\"' : \"\"}>\n ${itemsHtml}\n </div>\n <template data-frs-array-tpl>${templateHtml}</template>\n <button type=\"button\" class=\"btn btn-xs btn-outline mt-1\" data-frs-array-add>+ Add</button>\n ${nullToggle}\n </fieldset>`;\n}\n\nfunction renderPrimitiveItem(\n field: FieldDescriptor,\n value: unknown,\n): string {\n const strVal = value != null ? String(value) : \"\";\n let inputHtml: string;\n\n switch (field.arrayElementType) {\n case \"select\":\n inputHtml = `<select data-frs-val class=\"select select-bordered select-sm flex-1\">\n <option value=\"\">—</option>\n ${(field.arrayElementOptions ?? []).map((o) => `<option value=\"${e(o)}\"${strVal === o ? \" selected\" : \"\"}>${e(o)}</option>`).join(\"\")}\n </select>`;\n break;\n case \"checkbox\":\n inputHtml = `<label class=\"flex items-center gap-2 flex-1 cursor-pointer\">\n <input type=\"checkbox\" data-frs-val class=\"checkbox checkbox-sm checkbox-primary\"${strVal === \"true\" ? \" checked\" : \"\"}>\n <span class=\"text-sm\">true</span>\n </label>`;\n break;\n case \"number\":\n inputHtml = `<input type=\"number\" data-frs-val value=\"${e(strVal)}\" class=\"input input-bordered input-sm flex-1\">`;\n break;\n case \"datetime-local\":\n inputHtml = `<input type=\"datetime-local\" data-frs-val value=\"${e(strVal)}\" class=\"input input-bordered input-sm flex-1\">`;\n break;\n default:\n inputHtml = `<input type=\"text\" data-frs-val value=\"${e(strVal)}\" class=\"input input-bordered input-sm flex-1\">`;\n }\n\n return `<div class=\"flex items-center gap-2 mb-2\" data-frs-array-item>\n ${inputHtml}\n <button type=\"button\" class=\"btn btn-xs btn-ghost text-error\" data-frs-array-rm>&times;</button>\n </div>`;\n}\n\nfunction renderObjectItem(\n field: FieldDescriptor,\n obj: Record<string, unknown>,\n): string {\n const elFields = field.arrayElementFields ?? [];\n\n const fieldsHtml = elFields\n .map((f) => {\n const val = obj[f.name];\n const strVal =\n val == null\n ? \"\"\n : typeof val === \"object\"\n ? JSON.stringify(val)\n : String(val);\n\n switch (f.type) {\n case \"checkbox\":\n return `<div class=\"form-control mb-2\">\n <label class=\"label cursor-pointer justify-start gap-3\">\n <input type=\"checkbox\" data-frs-key=\"${e(f.name)}\" class=\"checkbox checkbox-sm checkbox-primary\"${strVal === \"true\" ? \" checked\" : \"\"}>\n <span class=\"label-text text-sm\">${e(f.label)}</span>\n </label>\n </div>`;\n case \"select\":\n return `<div class=\"form-control mb-2\">\n <label class=\"label pb-1\"><span class=\"label-text text-sm\">${e(f.label)}</span></label>\n <select data-frs-key=\"${e(f.name)}\" class=\"select select-bordered select-sm w-full\">\n ${f.required ? \"\" : `<option value=\"\">—</option>`}\n ${(f.options ?? []).map((o) => `<option value=\"${e(o)}\"${strVal === o ? \" selected\" : \"\"}>${e(o)}</option>`).join(\"\")}\n </select>\n </div>`;\n case \"number\":\n return `<div class=\"form-control mb-2\">\n <label class=\"label pb-1\"><span class=\"label-text text-sm\">${e(f.label)}</span></label>\n <input type=\"number\" data-frs-key=\"${e(f.name)}\" value=\"${e(strVal)}\" class=\"input input-bordered input-sm w-full\">\n </div>`;\n case \"datetime-local\":\n return `<div class=\"form-control mb-2\">\n <label class=\"label pb-1\"><span class=\"label-text text-sm\">${e(f.label)}</span></label>\n <input type=\"datetime-local\" data-frs-key=\"${e(f.name)}\" value=\"${e(strVal)}\" class=\"input input-bordered input-sm w-full\">\n </div>`;\n case \"textarea\":\n return `<div class=\"form-control mb-2\">\n <label class=\"label pb-1\"><span class=\"label-text text-sm\">${e(f.label)}</span></label>\n <textarea data-frs-key=\"${e(f.name)}\" rows=\"2\" class=\"textarea textarea-bordered textarea-sm w-full font-mono text-xs\" placeholder=\"JSON\">${e(strVal)}</textarea>\n </div>`;\n default:\n return `<div class=\"form-control mb-2\">\n <label class=\"label pb-1\"><span class=\"label-text text-sm\">${e(f.label)}</span></label>\n <input type=\"text\" data-frs-key=\"${e(f.name)}\" value=\"${e(strVal)}\" class=\"input input-bordered input-sm w-full\">\n </div>`;\n }\n })\n .join(\"\\n\");\n\n return `<div class=\"border border-base-200 rounded p-3 mb-2\" data-frs-array-item>\n <div class=\"flex justify-end mb-1\">\n <button type=\"button\" class=\"btn btn-xs btn-ghost text-error\" data-frs-array-rm>&times;</button>\n </div>\n ${fieldsHtml}\n </div>`;\n}\n\n// ---------------------------------------------------------------------------\n// Full form render\n// ---------------------------------------------------------------------------\n\nexport function renderForm(\n fields: FieldDescriptor[],\n action: string,\n method: \"GET\" | \"POST\",\n submitLabel = \"Save\",\n): string {\n const fieldsHtml = fields.map((f) => renderField(f)).join(\"\\n\");\n return `\n <form action=\"${e(action)}\" method=\"${method}\" novalidate data-frs-form>\n ${fieldsHtml}\n <div class=\"flex gap-2 mt-4 pt-4 border-t border-base-200\">\n <button type=\"submit\" class=\"btn btn-primary btn-sm\">${e(submitLabel)}</button>\n <button type=\"button\" class=\"btn btn-ghost btn-sm\" onclick=\"history.back()\">Cancel</button>\n </div>\n </form>`;\n}\n","function CellDate({ val }: { val: Date }) {\n return (\n <span class=\"text-sm text-base-content/80 font-mono tabular-nums whitespace-nowrap\">\n {val.toLocaleString()}\n </span>\n );\n}\n\nexport function CellValue({ val }: { val: unknown }) {\n if (val === null || val === undefined) {\n return <span class=\"opacity-30 italic text-xs\">—</span>;\n }\n\n if (typeof val === \"boolean\") {\n return val ? (\n <span class=\"badge badge-success badge-sm\">true</span>\n ) : (\n <span class=\"badge badge-error badge-sm\">false</span>\n );\n }\n\n if (val instanceof Date) {\n return <CellDate val={val} />;\n }\n\n // Firestore Timestamp (.toDate())\n if (\n typeof val === \"object\" &&\n val !== null &&\n typeof (val as any).toDate === \"function\"\n ) {\n return <CellDate val={(val as any).toDate() as Date} />;\n }\n\n if (typeof val === \"number\") {\n return <span class=\"text-sm font-mono tabular-nums\">{String(val)}</span>;\n }\n\n if (Array.isArray(val)) {\n if (val.length === 0)\n return <span class=\"text-xs text-base-content/30\">{\"[]\"}</span>;\n return (\n <ul class=\"list-none p-0 m-0 space-y-0.5 text-xs\">\n {val.slice(0, 8).map((item, i) => (\n <li key={i} class=\"break-all\">\n {typeof item === \"object\" ? JSON.stringify(item) : String(item)}\n </li>\n ))}\n {val.length > 8 && (\n <li class=\"text-base-content/40 italic\">\n +{val.length - 8} more…\n </li>\n )}\n </ul>\n );\n }\n\n if (typeof val === \"object\" && val !== null) {\n const entries = Object.entries(val as Record<string, unknown>);\n if (entries.length === 0)\n return <span class=\"text-xs text-base-content/30\">{\"{}\"}</span>;\n return (\n <dl class=\"grid grid-cols-[auto_1fr] gap-x-2 gap-y-0.5 text-xs m-0\">\n {entries.slice(0, 8).map(([k, v]) => (\n <>\n <dt class=\"text-base-content/50 font-semibold whitespace-nowrap\">\n {k}\n </dt>\n <dd class=\"break-all\">{String(v ?? \"\")}</dd>\n </>\n ))}\n {entries.length > 8 && (\n <dt class=\"col-span-2 text-base-content/40 italic\">\n +{entries.length - 8} more…\n </dt>\n )}\n </dl>\n );\n }\n\n const str = String(val);\n return <span class=\"text-sm break-all\">{str}</span>;\n}\n","// ── Form validation + array serialization ───────────────────────────────────\ndocument.addEventListener(\"submit\", function (e) {\n var form = e.target;\n if (!form.hasAttribute(\"data-frs-form\")) return;\n\n // 1. Validate JSON textareas\n var valid = true;\n form.querySelectorAll(\"textarea[data-json]\").forEach(function (ta) {\n var v = ta.value.trim();\n if (!v) return;\n try {\n JSON.parse(v);\n } catch (err) {\n valid = false;\n e.preventDefault();\n alert('Invalid JSON in field \"' + ta.name + '\":\\n' + err.message);\n }\n });\n if (!valid) return;\n\n // 2. Serialize array fields into hidden inputs\n form.querySelectorAll(\"[data-frs-array]\").forEach(function (fieldset) {\n var hidden = fieldset.querySelector(\"input[type=hidden][name]\");\n if (!hidden || hidden.disabled) return;\n\n var type = fieldset.getAttribute(\"data-frs-array-type\");\n var items = fieldset.querySelectorAll(\"[data-frs-array-item]\");\n var arr = [];\n\n if (type === \"object\") {\n items.forEach(function (item) {\n var obj = {};\n item.querySelectorAll(\"[data-frs-key]\").forEach(function (inp) {\n var key = inp.getAttribute(\"data-frs-key\");\n if (inp.type === \"checkbox\") {\n obj[key] = inp.checked;\n } else if (inp.type === \"number\") {\n obj[key] = inp.value === \"\" ? null : Number(inp.value);\n } else if (inp.tagName === \"TEXTAREA\") {\n var v = inp.value.trim();\n if (v) {\n try {\n obj[key] = JSON.parse(v);\n } catch (_) {\n obj[key] = v;\n }\n } else {\n obj[key] = null;\n }\n } else {\n obj[key] = inp.value;\n }\n });\n arr.push(obj);\n });\n } else {\n items.forEach(function (item) {\n var inp = item.querySelector(\"[data-frs-val]\");\n if (!inp) return;\n if (type === \"checkbox\") {\n arr.push(inp.checked);\n } else if (type === \"number\") {\n if (inp.value !== \"\") arr.push(Number(inp.value));\n } else {\n if (inp.value !== \"\") arr.push(inp.value);\n }\n });\n }\n\n hidden.value = JSON.stringify(arr);\n });\n});\n\n// ── Array add / remove buttons ──────────────────────────────────────────────\ndocument.addEventListener(\"click\", function (e) {\n // Add item\n var addBtn = e.target.closest(\"[data-frs-array-add]\");\n if (addBtn) {\n var fieldset = addBtn.closest(\"[data-frs-array]\");\n if (!fieldset) return;\n var tpl = fieldset.querySelector(\"template[data-frs-array-tpl]\");\n var container = fieldset.querySelector(\"[data-frs-array-items]\");\n if (!tpl || !container) return;\n var clone = tpl.content.cloneNode(true);\n container.appendChild(clone);\n var last = container.lastElementChild;\n if (last) {\n var firstInp = last.querySelector(\"input,select,textarea\");\n if (firstInp) firstInp.focus();\n }\n return;\n }\n\n // Remove item\n var rmBtn = e.target.closest(\"[data-frs-array-rm]\");\n if (rmBtn) {\n var item = rmBtn.closest(\"[data-frs-array-item]\");\n if (item) item.remove();\n }\n});\n\n// ── Table enhancements ──────────────────────────────────────────────────────\ndocument.addEventListener(\"DOMContentLoaded\", function () {\n document.querySelectorAll(\"table[data-frs-table]\").forEach(initTable);\n});\n\nfunction initTable(table) {\n tagOriginalIndices(table);\n applySavedColumnOrder(table);\n initColumnResize(table);\n initColumnVisibility(table);\n initColumnReorder(table);\n}\n\n// ── Tag original column indices ─────────────────────────────────────────────\nfunction tagOriginalIndices(table) {\n var ths = Array.from(table.querySelectorAll(\"thead th\"));\n var dataCount = countDataColumns(table, ths);\n for (var i = 0; i < dataCount; i++) {\n ths[i].setAttribute(\"data-orig-col\", String(i));\n }\n table.querySelectorAll(\"tbody tr\").forEach(function (row) {\n var tds = Array.from(row.querySelectorAll(\"td\"));\n for (var j = 0; j < dataCount && j < tds.length; j++) {\n tds[j].setAttribute(\"data-orig-col\", String(j));\n }\n });\n}\n\nfunction countDataColumns(table, ths) {\n var explicit = table.getAttribute(\"data-frs-colcount\");\n if (explicit) return parseInt(explicit, 10);\n var count = 0;\n for (var i = 0; i < ths.length; i++) {\n if (ths[i].querySelector(\"a[href]\")) count++;\n else break;\n }\n return count || Math.max(0, ths.length - 1);\n}\n\n// ── Apply saved column order ────────────────────────────────────────────────\nfunction applySavedColumnOrder(table) {\n var repo = table.getAttribute(\"data-frs-repo\") || \"default\";\n var saved;\n try {\n saved = JSON.parse(localStorage.getItem(\"frs_colorder_\" + repo));\n } catch (_) {\n return;\n }\n if (!saved || !Array.isArray(saved) || saved.length === 0) return;\n reorderColumns(table, saved);\n}\n\n// ── Reorder columns by orig-index array ─────────────────────────────────────\nfunction reorderColumns(table, order) {\n var headRow = table.querySelector(\"thead tr\");\n if (!headRow) return;\n reorderRow(headRow, order);\n table.querySelectorAll(\"tbody tr\").forEach(function (row) {\n reorderRow(row, order);\n });\n}\n\nfunction reorderRow(row, order) {\n var cells = Array.from(row.children);\n var dataCells = cells.filter(function (c) {\n return c.hasAttribute(\"data-orig-col\");\n });\n var tailCells = cells.filter(function (c) {\n return !c.hasAttribute(\"data-orig-col\");\n });\n var cellMap = {};\n dataCells.forEach(function (c) {\n cellMap[c.getAttribute(\"data-orig-col\")] = c;\n });\n while (row.firstChild) row.removeChild(row.firstChild);\n order.forEach(function (origIdx) {\n if (cellMap[origIdx]) row.appendChild(cellMap[origIdx]);\n });\n dataCells.forEach(function (c) {\n if (!row.contains(c)) row.appendChild(c);\n });\n tailCells.forEach(function (c) {\n row.appendChild(c);\n });\n}\n\n// ── Column resize ───────────────────────────────────────────────────────────\nfunction initColumnResize(table) {\n var ths = Array.from(table.querySelectorAll(\"thead th\"));\n ths.forEach(function (th, i) {\n if (i === ths.length - 1) return;\n th.style.position = \"relative\";\n var handle = document.createElement(\"div\");\n handle.style.cssText =\n \"position:absolute;right:0;top:0;bottom:0;width:5px;cursor:col-resize;z-index:10;\";\n handle.addEventListener(\"mousedown\", function (e) {\n e.preventDefault();\n e.stopPropagation();\n var startX = e.clientX,\n startW = th.offsetWidth;\n var line = document.createElement(\"div\");\n line.style.cssText =\n \"position:fixed;top:0;bottom:0;width:2px;background:oklch(0.585 0.233 277.117);opacity:0.5;pointer-events:none;z-index:9999;\";\n line.style.left = e.clientX + \"px\";\n document.body.appendChild(line);\n function onMove(ev) {\n var newW = Math.max(40, startW + ev.clientX - startX);\n th.style.width = newW + \"px\";\n th.style.minWidth = newW + \"px\";\n line.style.left = ev.clientX + \"px\";\n }\n function onUp() {\n document.body.removeChild(line);\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n }\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n });\n th.appendChild(handle);\n });\n}\n\n// ── Column visibility (Columns dropdown with checkboxes) ────────────────────\nfunction initColumnVisibility(table) {\n var dataThs = Array.from(table.querySelectorAll(\"thead th[data-orig-col]\"));\n if (dataThs.length === 0) return;\n\n var wrap = table.closest(\"[data-frs-table-wrap]\");\n var toolbar = wrap && wrap.previousElementSibling;\n if (!toolbar) return;\n\n var repo = table.getAttribute(\"data-frs-repo\") || \"default\";\n var storageKey = \"frs_cols_\" + repo;\n var savedState = {};\n try {\n savedState = JSON.parse(localStorage.getItem(storageKey) || \"{}\");\n } catch (_) {}\n\n function saveState(origIdx, visible) {\n savedState[origIdx] = visible;\n try {\n localStorage.setItem(storageKey, JSON.stringify(savedState));\n } catch (_) {}\n }\n\n function setColVisible(origIdx, visible) {\n var th = table.querySelector('thead th[data-orig-col=\"' + origIdx + '\"]');\n if (th) th.style.display = visible ? \"\" : \"none\";\n table\n .querySelectorAll('tbody td[data-orig-col=\"' + origIdx + '\"]')\n .forEach(function (td) {\n td.style.display = visible ? \"\" : \"none\";\n });\n }\n\n var cols = dataThs.map(function (th) {\n var origIdx = parseInt(th.getAttribute(\"data-orig-col\"), 10);\n return {\n origIndex: origIdx,\n label: th.textContent.replace(/\\s+/g, \" \").trim(),\n };\n });\n\n // Build dropdown\n var dropdown = document.createElement(\"div\");\n dropdown.className = \"dropdown dropdown-end\";\n\n var btn = document.createElement(\"button\");\n btn.type = \"button\";\n btn.tabIndex = 0;\n btn.className = \"btn btn-sm btn-outline gap-1\";\n btn.innerHTML =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"size-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\">' +\n '<path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 4v16M15 4v16M4 9h16M4 15h16\"/>' +\n \"</svg> Columns\";\n dropdown.appendChild(btn);\n\n var menu = document.createElement(\"ul\");\n menu.tabIndex = 0;\n menu.className =\n \"dropdown-content menu bg-base-100 rounded-box z-50 p-2 shadow-lg border border-base-300 w-56 max-h-80 overflow-y-auto flex-nowrap\";\n\n cols.forEach(function (col) {\n var li = document.createElement(\"li\");\n var label = document.createElement(\"label\");\n label.className =\n \"flex items-center gap-2 cursor-pointer px-2 py-1.5 rounded hover:bg-base-200\";\n\n var cb = document.createElement(\"input\");\n cb.type = \"checkbox\";\n cb.className = \"checkbox checkbox-xs checkbox-primary\";\n var isVisible = savedState[col.origIndex] !== false;\n cb.checked = isVisible;\n\n var span = document.createElement(\"span\");\n span.className = \"text-sm select-none\";\n span.textContent = col.label || \"Column \" + (col.origIndex + 1);\n\n label.appendChild(cb);\n label.appendChild(span);\n li.appendChild(label);\n\n if (!isVisible) setColVisible(col.origIndex, false);\n\n cb.addEventListener(\"change\", function (e) {\n var visible = e.target.checked;\n setColVisible(col.origIndex, visible);\n saveState(col.origIndex, visible);\n });\n\n menu.appendChild(li);\n });\n\n dropdown.appendChild(menu);\n toolbar.appendChild(dropdown);\n}\n\n// ── Column reorder (drag grip handles on headers) ───────────────────────────\nfunction initColumnReorder(table) {\n var repo = table.getAttribute(\"data-frs-repo\") || \"default\";\n var orderKey = \"frs_colorder_\" + repo;\n var dragSrcTh = null;\n var allDataThs = Array.from(\n table.querySelectorAll(\"thead th[data-orig-col]\"),\n );\n if (allDataThs.length < 2) return;\n\n allDataThs.forEach(function (th) {\n // Prepend a drag grip\n var grip = document.createElement(\"span\");\n grip.draggable = true;\n grip.textContent = \"\\u2807\";\n grip.style.cssText =\n \"cursor:grab;opacity:0.18;margin-right:4px;font-size:14px;vertical-align:middle;user-select:none;display:inline-block;\";\n grip.addEventListener(\"mouseenter\", function () {\n grip.style.opacity = \"0.5\";\n });\n grip.addEventListener(\"mouseleave\", function () {\n grip.style.opacity = \"0.18\";\n });\n th.insertBefore(grip, th.firstChild);\n\n // Drag starts from the grip only\n grip.addEventListener(\"dragstart\", function (e) {\n dragSrcTh = th;\n th.style.opacity = \"0.35\";\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", \"col\");\n try {\n e.dataTransfer.setDragImage(th, 20, 16);\n } catch (_) {}\n });\n\n grip.addEventListener(\"dragend\", function () {\n if (dragSrcTh) dragSrcTh.style.opacity = \"\";\n dragSrcTh = null;\n allDataThs.forEach(function (t) {\n t.style.boxShadow = \"\";\n });\n });\n\n // Drop target is the full <th>\n th.addEventListener(\"dragover\", function (e) {\n if (!dragSrcTh || dragSrcTh === th) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n allDataThs.forEach(function (t) {\n t.style.boxShadow = \"\";\n });\n var rect = th.getBoundingClientRect();\n var midX = rect.left + rect.width / 2;\n if (e.clientX < midX) {\n th.style.boxShadow = \"inset 3px 0 0 oklch(0.585 0.233 277.117)\";\n } else {\n th.style.boxShadow = \"inset -3px 0 0 oklch(0.585 0.233 277.117)\";\n }\n });\n\n th.addEventListener(\"dragleave\", function () {\n th.style.boxShadow = \"\";\n });\n\n th.addEventListener(\"drop\", function (e) {\n e.preventDefault();\n if (!dragSrcTh || dragSrcTh === th) return;\n allDataThs.forEach(function (t) {\n t.style.boxShadow = \"\";\n });\n\n var headRow = th.parentNode;\n var rect = th.getBoundingClientRect();\n var midX = rect.left + rect.width / 2;\n if (e.clientX < midX) {\n headRow.insertBefore(dragSrcTh, th);\n } else {\n headRow.insertBefore(dragSrcTh, th.nextElementSibling);\n }\n\n // Read new order from the reordered thead\n var newOrder = Array.from(\n table.querySelectorAll(\"thead th[data-orig-col]\"),\n ).map(function (t) {\n return parseInt(t.getAttribute(\"data-orig-col\"), 10);\n });\n\n // Apply the same order to all tbody rows\n table.querySelectorAll(\"tbody tr\").forEach(function (row) {\n reorderRow(row, newOrder);\n });\n\n // Persist\n try {\n localStorage.setItem(orderKey, JSON.stringify(newOrder));\n } catch (_) {}\n });\n });\n}\n","import JS from \"./client-script.raw.js\";\n\nexport function ClientScript() {\n // dangerouslySetInnerHTML is required here: JSX would escape < > & inside\n // a <script> text child, breaking the JavaScript at runtime.\n return <script dangerouslySetInnerHTML={{ __html: JS }} />;\n}\n","import type { Child, FC, PropsWithChildren } from \"hono/jsx\";\nimport { renderToString } from \"hono/jsx/dom/server\";\nimport { ClientScript } from \"./client-script\";\nimport type { PageOptions } from \"./types\";\n\n/** Render a JSX element to a complete HTML string (includes <!DOCTYPE html>) */\nexport function renderHtml(element: Child): string {\n return \"<!DOCTYPE html>\" + renderToString(element);\n}\n\nexport const PageShell: FC<PropsWithChildren<{ opts: PageOptions }>> = ({\n opts,\n children,\n}) => {\n const { title, breadcrumb, flash, basePath = \"/\" } = opts;\n\n return (\n <html lang=\"en\" data-theme=\"corporate\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>{title} — FRS Admin</title>\n <link\n href=\"https://cdn.jsdelivr.net/npm/daisyui@5/themes.css\"\n rel=\"stylesheet\"\n type=\"text/css\"\n />\n <link\n href=\"https://cdn.jsdelivr.net/npm/daisyui@5/daisyui.css\"\n rel=\"stylesheet\"\n type=\"text/css\"\n />\n <script src=\"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4\" />\n </head>\n <body class=\"bg-base-200/50 min-h-screen flex flex-col\">\n {/* Navbar */}\n <div class=\"navbar bg-neutral text-neutral-content shadow-sm sticky top-0 z-50 px-6\">\n <div class=\"flex-1\">\n <a\n href={basePath}\n class=\"font-bold text-lg tracking-tight hover:opacity-80 transition-opacity\"\n >\n FRS Admin\n </a>\n </div>\n </div>\n\n <main class=\"px-6 py-8 w-full flex-1\">\n {/* Breadcrumbs */}\n {breadcrumb && breadcrumb.length > 0 && (\n <div class=\"text-sm breadcrumbs mb-4\">\n <ul>\n {breadcrumb.map((c, i) =>\n c.href ? (\n <li key={i}>\n <a href={c.href}>{c.label}</a>\n </li>\n ) : (\n <li key={i} class=\"text-base-content/60\">\n {c.label}\n </li>\n ),\n )}\n </ul>\n </div>\n )}\n\n <h1 class=\"text-2xl font-bold mb-6\">{title}</h1>\n\n {/* Flash message */}\n {flash && (\n <div\n role=\"alert\"\n class={`alert ${flash.type === \"success\" ? \"alert-success\" : \"alert-error\"} mb-6`}\n >\n <span>{flash.message}</span>\n </div>\n )}\n\n {children}\n </main>\n\n <ClientScript />\n </body>\n </html>\n );\n};\n\n/** Wrap a raw HTML string in the page shell (backward compat). */\nexport function renderPageJsx(content: string, opts: PageOptions): string {\n return renderHtml(\n <PageShell opts={opts}>\n <div dangerouslySetInnerHTML={{ __html: content }} />\n </PageShell>,\n );\n}\n","import { PageShell, renderHtml } from \"./shell\";\n\nexport function renderDashboardJsx(\n repos: { name: string; path: string }[],\n basePath: string,\n): string {\n return renderHtml(\n <PageShell opts={{ title: \"Repositories\", basePath }}>\n {repos.length === 0 ? (\n <div class=\"text-center py-20 text-base-content/50\">\n <p class=\"text-lg font-medium mb-1\">No repositories configured</p>\n <p class=\"text-sm\">\n Add a repository to your FRS config to get started.\n </p>\n </div>\n ) : (\n <div class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4\">\n {repos.map((r) => (\n <a\n key={r.name}\n href={`${basePath}/${r.name}`}\n class=\"card bg-base-100 border border-base-300 hover:shadow-md no-underline transition-shadow\"\n >\n <div class=\"card-body p-5\">\n <h2 class=\"card-title text-sm font-semibold\">{r.name}</h2>\n <p class=\"text-xs text-base-content/50 font-mono\">{r.path}</p>\n </div>\n </a>\n ))}\n </div>\n )}\n </PageShell>,\n );\n}\n","import type { ColumnMeta, FilterState, WhereOp } from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Operator definitions per Zod type\n// ---------------------------------------------------------------------------\n\ntype OpDef = { value: WhereOp; label: string };\n\nconst OPS_TEXT: OpDef[] = [\n { value: \"==\", label: \"=\" },\n { value: \"!=\", label: \"≠\" },\n];\nconst OPS_NUMERIC: OpDef[] = [\n { value: \"==\", label: \"=\" },\n { value: \"!=\", label: \"≠\" },\n { value: \"<\", label: \"<\" },\n { value: \"<=\", label: \"≤\" },\n { value: \">\", label: \">\" },\n { value: \">=\", label: \"≥\" },\n];\nconst OPS_ARRAY: OpDef[] = [\n { value: \"array-contains\", label: \"contains\" },\n { value: \"array-contains-any\", label: \"contains any\" },\n];\n\nfunction opsForType(zodType: string): OpDef[] {\n switch (zodType) {\n case \"ZodNumber\":\n case \"ZodBigInt\":\n case \"ZodDate\":\n return OPS_NUMERIC;\n case \"ZodBoolean\":\n return OPS_TEXT;\n case \"ZodArray\":\n return OPS_ARRAY;\n default:\n return OPS_TEXT;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Value input per type\n// ---------------------------------------------------------------------------\n\nfunction FilterValueInput({\n col,\n active,\n}: {\n col: ColumnMeta;\n active?: FilterState;\n}) {\n const val = active?.value ?? \"\";\n\n if (col.zodType === \"ZodBoolean\") {\n return (\n <select\n name={`fv_${col.name}`}\n class=\"select select-sm select-bordered w-full\"\n >\n <option value=\"\" selected={val === \"\"}>\n —\n </option>\n <option value=\"true\" selected={val === \"true\"}>\n true\n </option>\n <option value=\"false\" selected={val === \"false\"}>\n false\n </option>\n </select>\n );\n }\n if (col.zodType === \"ZodArray\") {\n const isAny = active?.op === \"array-contains-any\";\n return (\n <input\n type=\"text\"\n name={`fv_${col.name}`}\n value={val}\n placeholder={isAny ? \"val1, val2, …\" : \"value\"}\n class=\"input input-sm input-bordered w-full\"\n />\n );\n }\n if (col.zodType === \"ZodNumber\" || col.zodType === \"ZodBigInt\") {\n return (\n <input\n type=\"number\"\n name={`fv_${col.name}`}\n value={val}\n placeholder=\"value\"\n class=\"input input-sm input-bordered w-full\"\n />\n );\n }\n if (col.zodType === \"ZodDate\") {\n return (\n <input\n type=\"datetime-local\"\n name={`fv_${col.name}`}\n value={val}\n class=\"input input-sm input-bordered w-full\"\n />\n );\n }\n return (\n <input\n type=\"text\"\n name={`fv_${col.name}`}\n value={val}\n placeholder=\"value\"\n class=\"input input-sm input-bordered w-full\"\n />\n );\n}\n\n// ---------------------------------------------------------------------------\n// FilterBar\n// ---------------------------------------------------------------------------\n\nexport function FilterBar({\n action,\n columnMeta,\n activeFilters,\n}: {\n /** Form action URL (list page URL, without query params) */\n action: string;\n columnMeta: ColumnMeta[];\n activeFilters: FilterState[];\n}) {\n const activeMap = Object.fromEntries(activeFilters.map((f) => [f.field, f]));\n const hasActive = activeFilters.length > 0;\n\n // Columns that can be filtered (exclude pure-object columns)\n const filterable = columnMeta.filter(\n (c) => c.zodType !== \"ZodObject\" && c.zodType !== \"ZodRecord\",\n );\n\n return (\n <details\n class=\"collapse collapse-arrow bg-base-100 border border-base-300 rounded-box mb-6 shadow-sm\"\n open={hasActive ? true : undefined}\n >\n <summary class=\"collapse-title text-sm font-medium py-2 min-h-0\">\n Filters\n {hasActive && (\n <span class=\"badge badge-primary badge-sm ml-2\">\n {activeFilters.length} active\n </span>\n )}\n </summary>\n <div class=\"collapse-content pb-4 pt-2\">\n <form method=\"get\" action={action}>\n <div class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4\">\n {filterable.map((col) => {\n const ops = opsForType(col.zodType);\n const active = activeMap[col.name];\n const currentOp: WhereOp = active?.op ?? ops[0]!.value;\n return (\n <div key={col.name} class=\"flex flex-col gap-1.5\">\n <label class=\"text-xs font-semibold text-base-content/60 uppercase tracking-wide\">\n {col.name}\n </label>\n <div class=\"flex gap-1.5\">\n {ops.length > 1 ? (\n <select\n name={`fo_${col.name}`}\n class=\"select select-sm select-bordered w-20 shrink-0\"\n >\n {ops.map((o) => (\n <option\n key={o.value}\n value={o.value}\n selected={o.value === currentOp}\n >\n {o.label}\n </option>\n ))}\n </select>\n ) : (\n // Single op → hidden input, no select to clutter UI\n <input\n type=\"hidden\"\n name={`fo_${col.name}`}\n value={ops[0]!.value}\n />\n )}\n <FilterValueInput col={col} active={active} />\n </div>\n </div>\n );\n })}\n </div>\n\n <div class=\"flex gap-2 mt-4 pt-3 border-t border-base-200\">\n <button type=\"submit\" class=\"btn btn-sm btn-primary\">\n Apply\n </button>\n {hasActive && (\n <a href={action} class=\"btn btn-sm btn-ghost\">\n Clear\n </a>\n )}\n </div>\n </form>\n </div>\n </details>\n );\n}\n","import { PageShell, renderHtml } from \"./shell\";\nimport type { PageOptions } from \"./types\";\n\nexport function renderFormPageJsx(\n repoName: string,\n formHtml: string,\n mode: \"create\" | \"edit\",\n docId: string | null,\n basePath: string,\n flash?: PageOptions[\"flash\"],\n): string {\n const title =\n mode === \"create\"\n ? `Create ${repoName}`\n : `Edit ${repoName} / ${docId ?? \"\"}`;\n\n const crumbs =\n mode === \"create\"\n ? [\n { label: \"Repositories\", href: basePath },\n { label: repoName, href: `${basePath}/${repoName}` },\n { label: \"New document\" },\n ]\n : [\n { label: \"Repositories\", href: basePath },\n { label: repoName, href: `${basePath}/${repoName}` },\n { label: `Edit ${docId ?? \"\"}` },\n ];\n\n return renderHtml(\n <PageShell opts={{ title, breadcrumb: crumbs, basePath, flash }}>\n <div class=\"card bg-base-100 border border-base-300\">\n <div class=\"card-body p-6\">\n <div dangerouslySetInnerHTML={{ __html: formHtml }} />\n </div>\n </div>\n </PageShell>,\n );\n}\n","import { CellValue } from \"./cell-value\";\nimport { FilterBar } from \"./filter-bar\";\nimport { PageShell, renderHtml } from \"./shell\";\nimport type {\n ColumnMeta,\n FilterState,\n PageOptions,\n RelationalFieldMeta,\n SortState,\n} from \"./types\";\n\n/** Shared helper — gather filter params into URLSearchParams. */\nfunction baseParams(\n filters: FilterState[],\n sort?: SortState,\n pageSize?: number,\n): URLSearchParams {\n const p = new URLSearchParams();\n for (const f of filters) {\n p.set(`fv_${f.field}`, f.value);\n p.set(`fo_${f.field}`, f.op);\n }\n if (sort) {\n p.set(\"ob\", sort.field);\n p.set(\"od\", sort.dir);\n }\n if (pageSize) p.set(\"ps\", String(pageSize));\n return p;\n}\n\n/**\n * Build a query-string for pagination (preserves filters, sort, page-size).\n */\nfunction paginationHref(\n filters: FilterState[],\n cursor: string,\n dir: \"prev\" | \"next\",\n sort?: SortState,\n pageSize?: number,\n): string {\n const p = baseParams(filters, sort, pageSize);\n p.set(\"cursor\", cursor);\n p.set(\"dir\", dir);\n return `?${p.toString()}`;\n}\n\n/**\n * Build a query-string that toggles / cycles the sort on a column.\n * Clears the cursor so the user starts from page 1 of the new order.\n */\nfunction sortHref(\n col: string,\n current: SortState | undefined,\n filters: FilterState[],\n pageSize?: number,\n): string {\n const p = baseParams(filters, undefined, pageSize);\n if (current?.field === col) {\n if (current.dir === \"asc\") {\n p.set(\"ob\", col);\n p.set(\"od\", \"desc\");\n }\n // desc → no ob/od (back to default order)\n } else {\n p.set(\"ob\", col);\n p.set(\"od\", \"asc\");\n }\n return `?${p.toString()}`;\n}\n\n/** Build a query-string that changes page size (clears cursor). */\nfunction pageSizeHref(\n newPs: number,\n filters: FilterState[],\n sort?: SortState,\n): string {\n const p = baseParams(filters, sort, newPs);\n return `?${p.toString()}`;\n}\n\nexport function renderListJsx(\n repoName: string,\n docs: Record<string, unknown>[],\n columns: string[],\n basePath: string,\n pagination: {\n hasPrev: boolean;\n hasNext: boolean;\n prevCursor: string;\n nextCursor: string;\n },\n flash?: PageOptions[\"flash\"],\n columnMeta: ColumnMeta[] = [],\n activeFilters: FilterState[] = [],\n allowDelete = false,\n relationalMeta: RelationalFieldMeta[] = [],\n sortState?: SortState,\n currentPageSize?: number,\n): string {\n const listUrl = `${basePath}/${repoName}`;\n const createUrl = `${listUrl}/create`;\n\n return renderHtml(\n <PageShell\n opts={{\n title: repoName,\n breadcrumb: [\n { label: \"Repositories\", href: basePath },\n { label: repoName },\n ],\n basePath,\n flash,\n }}\n >\n {/* Filter panel */}\n {columnMeta.length > 0 && (\n <FilterBar\n action={listUrl}\n columnMeta={columnMeta}\n activeFilters={activeFilters}\n />\n )}\n\n {/* Toolbar */}\n <div class=\"flex flex-wrap justify-between items-center mb-4 gap-3\">\n <div class=\"flex items-center gap-3\">\n <span class=\"text-sm text-base-content/60\">\n {docs.length} document{docs.length !== 1 && \"s\"}\n </span>\n {/* Rows-per-page */}\n <div class=\"flex items-center gap-1.5 text-sm text-base-content/60\">\n <span>Rows</span>\n <div class=\"join\">\n {[10, 25, 50, 100].map((ps) => (\n <a\n key={ps}\n href={pageSizeHref(ps, activeFilters, sortState)}\n class={`join-item btn btn-xs ${currentPageSize === ps ? \"btn-active btn-primary\" : \"btn-outline\"}`}\n >\n {ps}\n </a>\n ))}\n </div>\n </div>\n </div>\n <a href={createUrl} class=\"btn btn-primary btn-sm\">\n + New\n </a>\n </div>\n\n {/* Table */}\n <div\n class=\"overflow-x-auto rounded-box border border-base-300 bg-base-100\"\n data-frs-table-wrap\n >\n <table\n class=\"table table-sm w-full\"\n data-frs-table\n data-frs-repo={repoName}\n data-frs-colcount={columns.length}\n >\n <thead>\n <tr class=\"bg-base-200/50\">\n {[...columns].map((c, i) => {\n const isSorted = sortState?.field === c;\n const arrow = isSorted\n ? sortState!.dir === \"asc\"\n ? \" ▲\"\n : \" ▼\"\n : \"\";\n return (\n <th\n key={i}\n class=\"text-xs font-semibold text-base-content/60 uppercase tracking-wide\"\n >\n <a\n href={sortHref(\n c,\n sortState,\n activeFilters,\n currentPageSize,\n )}\n class={`hover:text-base-content inline-flex items-center gap-0.5${isSorted ? \" text-primary font-bold\" : \"\"}`}\n >\n {c}\n {arrow}\n </a>\n </th>\n );\n })}\n {relationalMeta.map((m, i) => (\n <th\n key={`rel-${i}`}\n class=\"text-xs font-semibold text-base-content/60 uppercase tracking-wide\"\n >\n {m.column}\n </th>\n ))}\n <th class=\"text-xs font-semibold text-base-content/60 uppercase tracking-wide text-right\">\n Actions\n </th>\n </tr>\n </thead>\n <tbody>\n {docs.length === 0 ? (\n <tr>\n <td\n colspan={columns.length + relationalMeta.length + 1}\n class=\"text-center py-16 text-base-content/40\"\n >\n No documents found\n </td>\n </tr>\n ) : (\n docs.map((doc, rowIdx) => {\n const id = String(doc[\"docId\"] ?? doc[\"id\"] ?? \"\");\n const editUrl = `${basePath}/${repoName}/${encodeURIComponent(id)}/edit`;\n const deleteUrl = `${basePath}/${repoName}/${encodeURIComponent(id)}/delete`;\n return (\n <tr key={rowIdx} class=\"hover\">\n {columns.map((c, ci) => (\n <td key={ci} class=\"align-top py-2\">\n <CellValue val={doc[c]} />\n </td>\n ))}\n {relationalMeta.map((m, mi) => {\n const rawVal = doc[m.key];\n if (rawVal == null || rawVal === \"\") {\n return <td key={`rel-${mi}`} class=\"py-2\" />;\n }\n const href = `${basePath}/${m.targetRepo}?fv_${m.targetKey}=${encodeURIComponent(String(rawVal))}`;\n return (\n <td key={`rel-${mi}`} class=\"align-middle py-2\">\n <a\n href={href}\n class=\"btn btn-xs btn-ghost btn-outline\"\n >\n {m.column}\n </a>\n </td>\n );\n })}\n <td class=\"align-middle text-right whitespace-nowrap py-2\">\n <div class=\"flex gap-1 justify-end\">\n <a\n href={editUrl}\n class=\"btn btn-xs btn-outline\"\n >\n Edit\n </a>\n {allowDelete && (\n <form\n method=\"post\"\n action={deleteUrl}\n onsubmit=\"return confirm('Delete this document?')\"\n >\n <button\n type=\"submit\"\n class=\"btn btn-xs btn-error btn-outline\"\n >\n Delete\n </button>\n </form>\n )}\n </div>\n </td>\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n\n {/* Pagination */}\n {(pagination.hasPrev || pagination.hasNext) && (\n <div class=\"flex justify-center items-center mt-6 gap-2\">\n {pagination.hasPrev ? (\n <a\n href={paginationHref(\n activeFilters,\n pagination.prevCursor,\n \"prev\",\n sortState,\n currentPageSize,\n )}\n class=\"btn btn-sm btn-outline\"\n >\n ← Previous\n </a>\n ) : (\n <button class=\"btn btn-sm btn-outline\" disabled>\n ← Previous\n </button>\n )}\n {pagination.hasNext ? (\n <a\n href={paginationHref(\n activeFilters,\n pagination.nextCursor,\n \"next\",\n sortState,\n currentPageSize,\n )}\n class=\"btn btn-sm btn-outline\"\n >\n Next →\n </a>\n ) : (\n <button class=\"btn btn-sm btn-outline\" disabled>\n Next →\n </button>\n )}\n </div>\n )}\n </PageShell>,\n );\n}\n","/**\n * Admin UI renderer — HTML generation functions for the admin interface.\n * All HTML generation is done via JSX in components.tsx.\n * This file preserves the original public API for backward compatibility.\n *\n * @example\n * ```typescript\n * import {\n * renderPage,\n * renderDashboard,\n * renderList,\n * renderFormPage,\n * ClientScript,\n * CSS,\n * } from \"@lpdjs/firestore-repo-service/servers/admin\";\n *\n * // Render a complete page with shell\n * const html = renderPage(\"<h1>Content</h1>\", {\n * title: \"My Admin\",\n * basePath: \"/admin\",\n * });\n *\n * // Render dashboard listing all repositories\n * const dashboard = renderDashboard(\n * [\n * { name: \"users\", path: \"users\", docCount: 150 },\n * { name: \"posts\", path: \"posts\", docCount: 42 },\n * ],\n * \"/admin\"\n * );\n *\n * // Render document list with pagination\n * const list = renderList(\n * \"users\",\n * [{ docId: \"1\", name: \"John\" }, { docId: \"2\", name: \"Jane\" }],\n * [\"docId\", \"name\"],\n * \"/admin\",\n * { hasPrev: false, hasNext: true, prevCursor: \"\", nextCursor: \"abc123\" },\n * { type: \"success\", message: \"User created!\" }, // Optional flash\n * [{ key: \"name\", label: \"Name\" }], // Column metadata\n * [{ field: \"name\", op: \"==\", value: \"John\" }], // Active filters\n * true, // Allow delete\n * [{ key: \"docId\", column: \"Posts\", targetRepo: \"posts\", targetKey: \"userId\", type: \"many\" }],\n * { field: \"name\", direction: \"asc\" }, // Sort state\n * 25, // Current page size\n * );\n *\n * // Render create/edit form page\n * const form = renderFormPage(\n * \"users\",\n * \"<form>...</form>\",\n * \"edit\",\n * \"user-123\",\n * \"/admin\",\n * { type: \"error\", message: \"Validation failed\" }\n * );\n * ```\n */\n\nexport { ClientScript } from \"./components\";\nexport type {\n ColumnMeta,\n FilterState,\n PageOptions,\n RelationalFieldMeta,\n SortState,\n WhereOp,\n} from \"./components\";\n\n/** @deprecated Styles come from DaisyUI CDN — no inline CSS needed */\nexport const CSS = \"\";\n\nimport type {\n ColumnMeta,\n FilterState,\n PageOptions,\n RelationalFieldMeta,\n SortState,\n} from \"./components\";\nimport {\n renderDashboardJsx,\n renderFormPageJsx,\n renderListJsx,\n renderPageJsx,\n} from \"./components\";\n\nexport function renderPage(content: string, opts: PageOptions): string {\n return renderPageJsx(content, opts);\n}\n\nexport function renderDashboard(\n repos: { name: string; path: string; docCount?: number }[],\n basePath: string,\n): string {\n return renderDashboardJsx(repos, basePath);\n}\n\nexport function renderList(\n repoName: string,\n docs: Record<string, unknown>[],\n columns: string[],\n basePath: string,\n pagination: {\n hasPrev: boolean;\n hasNext: boolean;\n prevCursor: string;\n nextCursor: string;\n },\n flash?: PageOptions[\"flash\"],\n columnMeta?: ColumnMeta[],\n activeFilters?: FilterState[],\n allowDelete?: boolean,\n relationalMeta?: RelationalFieldMeta[],\n sortState?: SortState,\n currentPageSize?: number,\n): string {\n return renderListJsx(\n repoName,\n docs,\n columns,\n basePath,\n pagination,\n flash,\n columnMeta,\n activeFilters,\n allowDelete,\n relationalMeta,\n sortState,\n currentPageSize,\n );\n}\n\nexport function renderFormPage(\n repoName: string,\n formHtml: string,\n mode: \"create\" | \"edit\",\n docId: string | null,\n basePath: string,\n flash?: PageOptions[\"flash\"],\n): string {\n return renderFormPageJsx(repoName, formHtml, mode, docId, basePath, flash);\n}\n","/**\n * HTTP route handlers for the admin ORM server.\n * Each handler corresponds to a URL pattern registered in the router.\n *\n * Routes:\n * GET / → dashboard GET /:repoName → document list (paginated)\n * GET /:repoName/create → create form\n * POST /:repoName/create → submit create\n * GET /:repoName/:id/edit → edit form (pre-filled)\n * POST /:repoName/:id/edit → submit update\n * POST /:repoName/:id/delete → delete document\n */\n\nimport { z } from \"zod\";\nimport type { ConfiguredRepository } from \"../../repositories/types\";\nimport type { RepositoryConfig } from \"../../shared/types\";\nimport { getInnerType, getShape, getTypeName } from \"../../shared/zod-compat\";\nimport { renderForm, zodToFields, type FieldDescriptor } from \"./form-gen\";\nimport type {\n ColumnMeta,\n FilterState,\n RelationalFieldMeta,\n WhereOp,\n} from \"./renderer\";\nimport { renderDashboard, renderFormPage, renderList } from \"./renderer\";\nimport type { AnyReq, AnyRes, RouteParams } from \"./router\";\n\n// ---------------------------------------------------------------------------\n// Registry type\n// ---------------------------------------------------------------------------\n\nexport interface AdminRepoEntry {\n name: string;\n path: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n repo: ConfiguredRepository<\n RepositoryConfig<any, any, any, any, any, any, any, any, any, any>\n >;\n schema: z.ZodObject<any>;\n /** document key field name (default: \"docId\") */\n documentKey?: string;\n /** Field name that stores the full Firestore document path (e.g. \"documentPath\") */\n pathKey?: string;\n /** Whether this repo is a collection group (subcollection) */\n isGroup?: boolean;\n /** Parent key field names needed to build a subcollection document ref (auto-detected from refCb) */\n parentKeys?: string[];\n /** Field name for the creation timestamp (auto-set on create) */\n createdKey?: string;\n /** List of columns to display in the table (defaults to schema keys) */\n listColumns?: string[];\n /** Page size for list view (default: 25) */\n pageSize?: number;\n /** Fields exposed in the filter bar (defaults to all schema keys) */\n filterableFields?: string[];\n /** Fields shown in the edit form (defaults to all schema fields if unset) */\n mutableFields?: string[];\n /** Fields shown in the create form (defaults to all schema fields if unset) */\n createFields?: string[];\n /** Whether delete is allowed (default: false) */\n allowDelete?: boolean;\n /**\n * Fields that link to another repository.\n * Populated automatically from the repo's relationalKeys.\n */\n relationalMeta?: RelationalFieldMeta[];\n}\n\nexport type RepoRegistry = Record<string, AdminRepoEntry>;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst _idChars =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\n/** Generate a random 20-char alphanumeric ID matching Firestore's native format. */\nfunction generateFirestoreId(): string {\n let id = \"\";\n for (let i = 0; i < 20; i++) {\n id += _idChars.charAt(Math.floor(Math.random() * _idChars.length));\n }\n return id;\n}\n\n/**\n * Extract Firestore document path args from a document's stored path.\n * e.g. \"posts/abc/comments/xyz\" → [\"abc\", \"xyz\"] (the doc-ID segments).\n * Returns `undefined` when no usable path is available.\n */\nfunction extractPathArgs(\n doc: Record<string, unknown>,\n pathKey?: string,\n): string[] | undefined {\n if (!pathKey) return undefined;\n const fullPath = doc[pathKey];\n if (typeof fullPath !== \"string\" || !fullPath) return undefined;\n const segments = fullPath.split(\"/\").filter(Boolean);\n // Doc IDs are at odd indices: col/id/col/id/...\n const args: string[] = [];\n for (let i = 1; i < segments.length; i += 2) {\n args.push(segments[i]!);\n }\n return args.length > 0 ? args : undefined;\n}\n\n/**\n * Fetch a single document by its documentKey, with fallback to query\n * for collection-group repos where direct documentRef may fail.\n */\nasync function fetchDocById(\n entry: AdminRepoEntry,\n docId: string,\n): Promise<Record<string, unknown> | null> {\n const docKey = entry.documentKey ?? \"docId\";\n const getMethod =\n `by${docKey.charAt(0).toUpperCase()}${docKey.slice(1)}` as keyof typeof entry.repo.get;\n\n // Try direct get first\n if (typeof entry.repo.get[getMethod] === \"function\") {\n try {\n const doc = (await (entry.repo.get[getMethod] as Function)(\n docId,\n )) as Record<string, unknown> | null;\n if (doc) return doc;\n } catch {\n // Direct ref may fail for subcollections — fall through to query\n }\n }\n\n // Fallback: query-based lookup (works for collectionGroup)\n const results = await entry.repo.query.by({\n where: [[docKey, \"==\", docId]],\n limit: 1,\n });\n return (results[0] as Record<string, unknown>) ?? null;\n}\n\nfunction sendHtml(res: AnyRes, html: string, status = 200): void {\n res.status(status).set(\"Content-Type\", \"text/html; charset=utf-8\").send(html);\n}\n\nfunction redirect(res: AnyRes, to: string): void {\n res.status(302).set(\"Location\", to).send(\"\");\n}\n\n/**\n * Parse a flat form body (from `application/x-www-form-urlencoded`) into a\n * typed object using the Zod schema as guide.\n * Handles: dot-notation nested fields (e.g. address.street), JSON textarea\n * values, booleans (checkbox), numbers.\n */\nfunction parseFormBody(\n raw: Record<string, string | string[] | undefined>,\n schema: z.ZodObject<any>,\n): Record<string, unknown> {\n const shape = schema.shape;\n const result: Record<string, unknown> = {};\n\n for (const [key, zodField] of Object.entries(shape)) {\n const tn = resolveTypeName(zodField as z.ZodType);\n\n // ── ZodObject: prefer dot-notation sub-keys over raw JSON textarea ──────\n if (tn === \"ZodObject\") {\n // Check for explicit null marker first\n if (raw[key + \"__isnull\"] === \"1\") {\n result[key] = null;\n continue;\n }\n const subRaw: Record<string, string | string[] | undefined> = {};\n let hasDotKeys = false;\n for (const [k, v] of Object.entries(raw)) {\n if (k.startsWith(`${key}.`)) {\n subRaw[k.slice(key.length + 1)] = v;\n hasDotKeys = true;\n }\n }\n if (hasDotKeys) {\n // Unwrap to the inner ZodObject schema and recurse\n let innerSchema: z.ZodType = zodField as z.ZodType;\n while (true) {\n const itn = getTypeName(innerSchema);\n if (\n itn === \"ZodOptional\" ||\n itn === \"ZodNullable\" ||\n itn === \"ZodDefault\"\n ) {\n innerSchema = getInnerType(innerSchema)!;\n } else break;\n }\n result[key] = parseFormBody(subRaw, innerSchema as z.ZodObject<any>);\n continue;\n }\n // Fallback: try to JSON-parse the textarea value\n const rawVal = raw[key];\n const strVal = Array.isArray(rawVal) ? rawVal[rawVal.length - 1] : rawVal;\n if (strVal) {\n try {\n result[key] = JSON.parse(strVal);\n } catch {\n result[key] = strVal;\n }\n }\n continue;\n }\n\n // ── All other types ─────────────────────────────────────────────────────\n const rawVal = raw[key];\n const strVal = Array.isArray(rawVal) ? rawVal[rawVal.length - 1] : rawVal;\n // Nullable field explicitly set to null via the toggle\n if (raw[key + \"__isnull\"] === \"1\") {\n result[key] = null;\n continue;\n }\n if (strVal === undefined || strVal === \"\") {\n // Checkbox unchecked → false; everything else → omit\n if (tn === \"ZodBoolean\") result[key] = false;\n continue;\n }\n\n switch (tn) {\n case \"ZodBoolean\":\n if (strVal === \"__null__\") {\n result[key] = null;\n } else {\n result[key] = strVal === \"true\" || strVal === \"on\" || strVal === \"1\";\n }\n break;\n case \"ZodNumber\":\n case \"ZodBigInt\":\n result[key] = Number(strVal);\n break;\n case \"ZodDate\":\n result[key] = new Date(strVal);\n break;\n case \"ZodArray\":\n try {\n result[key] = JSON.parse(strVal);\n } catch {\n result[key] = strVal;\n }\n break;\n default:\n // Try JSON for inline JSON textareas, fall back to string\n if (strVal.startsWith(\"{\") || strVal.startsWith(\"[\")) {\n try {\n result[key] = JSON.parse(strVal);\n break;\n } catch {\n /* fall through */\n }\n }\n result[key] = strVal;\n }\n }\n\n return result;\n}\n\n/**\n * Convert any date-like value to the \"yyyy-MM-ddThh:mm\" string required by\n * `<input type=\"datetime-local\">`.\n * Handles: native Date, Firestore Timestamp ({_seconds, _nanoseconds}),\n * Firestore Timestamp with .toDate(), ISO strings, unix numbers.\n */\nfunction toDatetimeLocal(val: unknown): string | null {\n let date: Date | null = null;\n\n if (val instanceof Date) {\n date = val;\n } else if (\n typeof val === \"object\" &&\n val !== null &&\n typeof (val as any).toDate === \"function\"\n ) {\n // Firestore Timestamp SDK object\n date = (val as any).toDate() as Date;\n } else if (\n typeof val === \"object\" &&\n val !== null &&\n \"_seconds\" in val &&\n \"_nanoseconds\" in val\n ) {\n // Plain serialized Firestore Timestamp { _seconds, _nanoseconds }\n date = new Date(\n (val as any)._seconds * 1000 +\n Math.floor((val as any)._nanoseconds / 1_000_000),\n );\n } else if (typeof val === \"string\" || typeof val === \"number\") {\n const d = new Date(val as string | number);\n if (!isNaN(d.getTime())) date = d;\n }\n\n if (!date || isNaN(date.getTime())) return null;\n\n // Format as local time yyyy-MM-ddThh:mm (what datetime-local expects)\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return (\n `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}` +\n `T${pad(date.getHours())}:${pad(date.getMinutes())}`\n );\n}\n\n/** Resolve the innermost Zod type name (unwrapping Optional/Nullable/Default) */\nfunction resolveTypeName(schema: z.ZodType): string {\n let s: z.ZodType = schema;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const tn = getTypeName(s);\n if (tn === \"ZodOptional\" || tn === \"ZodNullable\" || tn === \"ZodDefault\") {\n s = getInnerType(s)!;\n } else {\n return tn;\n }\n }\n}\n\n/**\n * Prefill a Zod schema fields with existing document values.\n * For ZodObject fields, recurses into nested sub-fields using dot-notation keys\n * so that individual sub-inputs (e.g. address.street) are properly pre-filled.\n */\nfunction prefillFromDoc(\n doc: Record<string, unknown>,\n schema: z.ZodObject<any>,\n prefix = \"\",\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const key of Object.keys(schema.shape)) {\n const fullKey = prefix ? `${prefix}.${key}` : key;\n const val = doc[key];\n // Sentinel \"__null__\" tells renderField to pre-check the null toggle\n if (val === null) {\n result[fullKey] = \"__null__\";\n continue;\n }\n if (val === undefined) continue;\n\n // Unwrap Optional/Nullable/Default to check inner type\n let innerSchema: z.ZodType = schema.shape[key] as z.ZodType;\n while (true) {\n const itn = getTypeName(innerSchema);\n if (\n itn === \"ZodOptional\" ||\n itn === \"ZodNullable\" ||\n itn === \"ZodDefault\"\n ) {\n innerSchema = getInnerType(innerSchema)!;\n } else break;\n }\n const innerTn = getTypeName(innerSchema);\n\n if (\n innerTn === \"ZodObject\" &&\n typeof val === \"object\" &&\n val !== null &&\n !Array.isArray(val)\n ) {\n // Recursively flatten nested object fields with dot-notation\n const nested = prefillFromDoc(\n val as Record<string, unknown>,\n innerSchema as z.ZodObject<any>,\n fullKey,\n );\n Object.assign(result, nested);\n } else if (innerTn === \"ZodDate\") {\n // Convert Date / Firestore Timestamp → datetime-local string\n const dtLocal = toDatetimeLocal(val);\n if (dtLocal !== null) result[fullKey] = dtLocal;\n } else if (\n typeof val === \"object\" &&\n val !== null &&\n !Array.isArray(val) &&\n (\"_seconds\" in val || typeof (val as any).toDate === \"function\")\n ) {\n // Untyped Timestamp-like value: try datetime-local, fall back to JSON\n const dtLocal = toDatetimeLocal(val);\n result[fullKey] = dtLocal ?? JSON.stringify(val, null, 2);\n } else if (typeof val === \"object\") {\n result[fullKey] = JSON.stringify(val, null, 2);\n } else {\n result[fullKey] = String(val);\n }\n }\n return result;\n}\n\n/**\n * Recursively apply prefilled string values to a tree of FieldDescriptors.\n * Handles dot-notation keys for nested objects (e.g. \"address.street\").\n */\nfunction applyPrefill(\n fields: FieldDescriptor[],\n prefilled: Record<string, string>,\n): FieldDescriptor[] {\n return fields.map((f) => ({\n ...f,\n defaultValue: prefilled[f.name] ?? f.defaultValue,\n nested: f.nested ? applyPrefill(f.nested, prefilled) : undefined,\n }));\n}\n\n// ---------------------------------------------------------------------------\n// Filter helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Extract active filters from URL query params.\n * Params: fv_{field} = value, fo_{field} = operator (default ==)\n */\nfunction parseFilters(\n query: Record<string, string>,\n validFields: Set<string>,\n): FilterState[] {\n const validOps = new Set<string>([\n \"==\",\n \"!=\",\n \"<\",\n \"<=\",\n \">\",\n \">=\",\n \"array-contains\",\n \"array-contains-any\",\n ]);\n const filters: FilterState[] = [];\n for (const [k, v] of Object.entries(query)) {\n if (!k.startsWith(\"fv_\")) continue;\n const field = k.slice(3);\n if (!validFields.has(field)) continue;\n const value = (v ?? \"\").trim();\n if (!value) continue;\n const opRaw = query[`fo_${field}`] ?? \"==\";\n const op = validOps.has(opRaw) ? (opRaw as WhereOp) : \"==\";\n filters.push({ field, op, value });\n }\n return filters;\n}\n\n/**\n * Convert FilterState[] to the where-clause tuples expected by the query engine.\n * Coerces string values to boolean/number when unambiguous.\n */\nfunction filtersToWhere(filters: FilterState[]): [string, WhereOp, unknown][] {\n const coerce = (v: string): unknown => {\n if (v === \"true\") return true;\n if (v === \"false\") return false;\n if (v !== \"\" && !isNaN(Number(v))) return Number(v);\n return v;\n };\n return filters.map((f) => {\n if (f.op === \"array-contains-any\") {\n // CSV list → array, each element coerced\n const arr = f.value\n .split(\",\")\n .map((s) => coerce(s.trim()))\n .filter((s) => s !== \"\");\n return [f.field, f.op, arr];\n }\n return [f.field, f.op, coerce(f.value)];\n });\n}\n\n/** Build ColumnMeta for displayable columns, recursing into ZodObject sub-fields (dot-notation). */\nfunction buildColumnMeta(\n columns: string[],\n schema: z.ZodObject<any>,\n prefix = \"\",\n): ColumnMeta[] {\n const result: ColumnMeta[] = [];\n for (const col of columns) {\n const fullName = prefix ? `${prefix}.${col}` : col;\n const field = schema.shape[col] as z.ZodType | undefined;\n if (!field) {\n result.push({ name: fullName, zodType: \"ZodString\" });\n continue;\n }\n const zodType = resolveTypeName(field);\n if (zodType === \"ZodObject\") {\n // Unwrap wrappers to reach the inner ZodObject\n let inner: z.ZodType = field;\n while (true) {\n const itn = getTypeName(inner);\n if (\n itn === \"ZodOptional\" ||\n itn === \"ZodNullable\" ||\n itn === \"ZodDefault\"\n ) {\n inner = getInnerType(inner)!;\n } else break;\n }\n const subShape = getShape(inner);\n result.push(\n ...buildColumnMeta(\n Object.keys(subShape),\n inner as z.ZodObject<any>,\n fullName,\n ),\n );\n } else {\n result.push({ name: fullName, zodType });\n }\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Handler factory\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the ZodType at a dot-notation path (e.g. \"address.city\") within a schema.\n * Returns null if the path cannot be resolved.\n */\nfunction resolveZodAtPath(\n schema: z.ZodObject<any>,\n path: string,\n): z.ZodType | null {\n const parts = path.split(\".\");\n let s: z.ZodType = schema as z.ZodType;\n for (const part of parts) {\n // Unwrap Optional / Nullable / Default wrappers\n while (true) {\n const itn = getTypeName(s);\n if (\n itn === \"ZodOptional\" ||\n itn === \"ZodNullable\" ||\n itn === \"ZodDefault\"\n ) {\n s = getInnerType(s)!;\n } else break;\n }\n const shape = getShape(s);\n if (!(part in shape)) return null;\n s = shape[part]!;\n }\n return s;\n}\n\n/**\n * Returns a Zod schema restricted to `fields` when defined.\n * Supports dot-notation paths (e.g. \"address.city\") by building partial\n * nested sub-schemas — useful for edit/create forms.\n * Falls back to the full schema if fields is undefined/empty.\n */\nfunction getMutableSchema(\n schema: z.ZodObject<any>,\n fields: string[] | undefined,\n): z.ZodObject<any> {\n if (!fields || fields.length === 0) return schema;\n\n const topLevel: string[] = [];\n // parent key → list of sub-field names requested\n const dotGroups = new Map<string, string[]>();\n\n for (const f of fields) {\n const dot = f.indexOf(\".\");\n if (dot === -1) {\n topLevel.push(f);\n } else {\n const parent = f.slice(0, dot);\n const child = f.slice(dot + 1);\n if (!dotGroups.has(parent)) dotGroups.set(parent, []);\n dotGroups.get(parent)!.push(child);\n }\n }\n\n const picked: Record<string, z.ZodType> = {};\n\n // Direct top-level fields\n for (const f of topLevel) {\n if (f in schema.shape) picked[f] = schema.shape[f]!;\n }\n\n // Partial nested objects for dot-notation entries\n for (const [parent, subFields] of dotGroups) {\n if (!(parent in schema.shape)) continue;\n // Unwrap to the inner ZodObject\n let inner: z.ZodType = schema.shape[parent] as z.ZodType;\n while (true) {\n const itn = getTypeName(inner);\n if (\n itn === \"ZodOptional\" ||\n itn === \"ZodNullable\" ||\n itn === \"ZodDefault\"\n ) {\n inner = getInnerType(inner)!;\n } else break;\n }\n if (getTypeName(inner) !== \"ZodObject\") {\n // Not an object — include as-is\n picked[parent] = schema.shape[parent]!;\n continue;\n }\n // Recurse: build a partial sub-schema for the requested sub-fields\n picked[parent] = getMutableSchema(inner as z.ZodObject<any>, subFields);\n }\n\n return z.object(picked);\n}\n/**\n * Compute the link base for all UI links.\n *\n * ── Emulator (FUNCTIONS_EMULATOR=true) ──────────────────────────────────────\n * Firebase emulator exposes functions at:\n * http://localhost:5001/{GCLOUD_PROJECT}/{FUNCTION_REGION}/{FUNCTION_TARGET}/...\n * env vars set by the emulator:\n * GCLOUD_PROJECT / GOOGLE_CLOUD_PROJECT → project id\n * FUNCTION_REGION → region (default: us-central1)\n * FUNCTION_TARGET → function export name (e.g. \"admin\")\n *\n * ── Production ──────────────────────────────────────────────────────────────\n * Firebase proxy strips the prefix before reaching the handler, so links\n * are relative to \"/\" and `staticBasePath` is used as-is.\n */\nfunction getLinkBase(req: AnyReq, staticBasePath: string): string {\n const base = staticBasePath === \"/\" ? \"\" : staticBasePath.replace(/\\/$/, \"\");\n\n if (process.env[\"FUNCTIONS_EMULATOR\"] === \"true\") {\n const project =\n process.env[\"GCLOUD_PROJECT\"] ??\n process.env[\"GOOGLE_CLOUD_PROJECT\"] ??\n \"demo-project\";\n const region = process.env[\"FUNCTION_REGION\"] ?? \"us-central1\";\n // FUNCTION_TARGET uses dots (e.g. \"sync.functions.adminsync\") but the\n // emulator URL uses hyphens (\"sync-functions-adminsync\").\n const target = (process.env[\"FUNCTION_TARGET\"] ?? \"\").replace(/\\./g, \"-\");\n return `/${project}/${region}/${target}${base}`;\n }\n\n // Cloud Functions v2: K_SERVICE = function name = URL path prefix.\n // Only add it when accessed via cloudfunctions.net (not custom domains).\n // Cloud Run (Gen 2) lowercases service names, but K_SERVICE may still\n // carry the original mixed-case export name — normalise to lowercase\n // so that generated links match the canonical URL.\n const service = process.env[\"K_SERVICE\"];\n const host: string =\n (req as any).hostname ?? (req.headers as any)?.[\"host\"] ?? \"\";\n if (service && host.includes(\"cloudfunctions.net\")) {\n return `/${service.toLowerCase()}${base}`;\n }\n\n return base;\n}\n\nexport function createAdminHandlers(registry: RepoRegistry, basePath: string) {\n // ── Dashboard ─────────────────────────────────────────────────────────────\n const handleDashboard = (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n ): void => {\n const lb = getLinkBase(req, basePath);\n const repos = Object.values(registry).map((e) => ({\n name: e.name,\n path: e.path,\n }));\n sendHtml(res, renderDashboard(repos, lb));\n };\n\n // ── List documents ────────────────────────────────────────────────────────\n const handleList = async (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n ): Promise<void> => {\n const repoName = req.params[\"repoName\"];\n if (!repoName) {\n sendHtml(res, \"Bad request\", 400);\n return;\n }\n const entry = registry[repoName];\n if (!entry) {\n sendHtml(res, \"Repository not found\", 404);\n return;\n }\n\n const pageSize = entry.pageSize ?? 25;\n const query = (req.query ?? {}) as Record<string, string>;\n const cursorStr = query[\"cursor\"];\n const dir = query[\"dir\"] === \"prev\" ? \"prev\" : \"next\";\n\n // Sort\n const sortField = query[\"ob\"] ?? \"\";\n const sortDir = (query[\"od\"] === \"desc\" ? \"desc\" : \"asc\") as \"asc\" | \"desc\";\n const sortState = sortField\n ? { field: sortField, dir: sortDir }\n : undefined;\n\n // Rows per page (query ?ps= overrides config, capped at 200)\n const psRaw = parseInt(query[\"ps\"] ?? \"\");\n const currentPageSize =\n Number.isFinite(psRaw) && psRaw > 0 ? Math.min(psRaw, 200) : pageSize;\n\n const allColumns = entry.listColumns ?? Object.keys(entry.schema.shape);\n const docKey = entry.documentKey ?? \"docId\";\n const columns = [docKey, ...allColumns.filter((c: string) => c !== docKey)];\n // Restrict filterable columns to filterableFields when defined.\n // Dot-notation paths (e.g. \"address.city\") are passed through directly;\n // top-level keys expand to sub-fields via buildColumnMeta as before.\n const filterableColumns: string[] = entry.filterableFields\n ? (() => {\n const out: string[] = [];\n for (const f of entry.filterableFields!) {\n if (f.includes(\".\")) {\n out.push(f); // direct dot-notation path\n } else if (allColumns.includes(f)) {\n out.push(f); // regular top-level key\n }\n }\n return out;\n })()\n : allColumns;\n // For dot-notation entries, resolve the correct ZodType; for top-level\n // keys, delegate to the existing buildColumnMeta (handles ZodObject expansion).\n const columnMeta: import(\"./renderer\").ColumnMeta[] = (() => {\n const out: import(\"./renderer\").ColumnMeta[] = [];\n for (const col of filterableColumns) {\n if (col.includes(\".\")) {\n const resolved = resolveZodAtPath(entry.schema, col);\n out.push({\n name: col,\n zodType: resolved ? resolveTypeName(resolved) : \"ZodString\",\n });\n } else {\n out.push(...buildColumnMeta([col], entry.schema));\n }\n }\n return out;\n })();\n\n // Parse and validate filters from query params\n // validFields built from columnMeta so dot-notation fields (address.city) are accepted\n const validFields = new Set(columnMeta.map((c) => c.name));\n const activeFilters = parseFilters(query, validFields);\n const whereFilters = filtersToWhere(activeFilters);\n\n // Attempt to rehydrate cursor\n let cursorSnapshot:\n | import(\"firebase-admin/firestore\").DocumentSnapshot\n | undefined;\n if (cursorStr) {\n try {\n const colRef = entry.repo.ref as any;\n if (typeof colRef.doc === \"function\") {\n cursorSnapshot = await colRef.doc(cursorStr).get();\n }\n } catch {\n /* ignore */\n }\n }\n\n const result = await entry.repo.query.paginate({\n pageSize: currentPageSize,\n cursor: cursorSnapshot,\n // direction + where + orderBy are supported at runtime but not in the strict typed interface\n ...{ direction: dir },\n ...(whereFilters.length > 0 ? { where: whereFilters } : {}),\n ...(sortState\n ? {\n orderBy: [\n { field: sortState.field as any, direction: sortState.dir },\n ],\n }\n : {}),\n });\n\n const nextCursorId = result.nextCursor?.id ?? \"\";\n const prevCursorId = result.prevCursor?.id ?? \"\";\n const lb = getLinkBase(req, basePath);\n\n sendHtml(\n res,\n renderList(\n entry.name,\n result.data as Record<string, unknown>[],\n columns,\n lb,\n {\n hasPrev: result.hasPrevPage,\n hasNext: result.hasNextPage,\n prevCursor: prevCursorId,\n nextCursor: nextCursorId,\n },\n undefined,\n columnMeta,\n activeFilters,\n entry.allowDelete ?? false,\n entry.relationalMeta,\n sortState,\n currentPageSize,\n ),\n );\n };\n\n // ── Create form ───────────────────────────────────────────────────────────\n const handleCreateForm = (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n ): void => {\n const repoName = req.params[\"repoName\"];\n if (!repoName) {\n sendHtml(res, \"Bad request\", 400);\n return;\n }\n const entry = registry[repoName];\n if (!entry) {\n sendHtml(res, \"Repository not found\", 404);\n return;\n }\n\n const lb = getLinkBase(req, basePath);\n const createSchema = getMutableSchema(entry.schema, entry.createFields);\n const fields = zodToFields(createSchema);\n const actionUrl = `${lb}/${entry.name}/create`;\n const formHtml = renderForm(fields, actionUrl, \"POST\", \"Create document\");\n\n sendHtml(res, renderFormPage(entry.name, formHtml, \"create\", null, lb));\n };\n\n // ── Create submit ─────────────────────────────────────────────────────────\n const handleCreateSubmit = async (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n ): Promise<void> => {\n const repoName = req.params[\"repoName\"];\n if (!repoName) {\n sendHtml(res, \"Bad request\", 400);\n return;\n }\n const entry = registry[repoName];\n if (!entry) {\n sendHtml(res, \"Repository not found\", 404);\n return;\n }\n\n const lb = getLinkBase(req, basePath);\n const rawBody =\n (req.body as Record<string, string | string[] | undefined>) ?? {};\n const parsed = parseFormBody(rawBody, entry.schema);\n const createSchema = getMutableSchema(entry.schema, entry.createFields);\n const validation = createSchema.safeParse(parsed);\n\n if (!validation.success) {\n const fields = zodToFields(createSchema);\n const actionUrl = `${lb}/${entry.name}/create`;\n const formHtml = renderForm(fields, actionUrl, \"POST\", \"Create document\");\n const errorMsg = validation.error.issues\n .map((e) => `${e.path.join(\".\")}: ${e.message}`)\n .join(\", \");\n sendHtml(\n res,\n renderFormPage(entry.name, formHtml, \"create\", null, lb, {\n type: \"error\",\n message: `Validation error: ${errorMsg}`,\n }),\n 422,\n );\n return;\n }\n\n try {\n if (entry.isGroup && entry.parentKeys && entry.parentKeys.length > 0) {\n // Collection-group repos cannot use create(); use set() with parent path args.\n const data: Record<string, any> = { ...validation.data };\n // set() doesn't auto-set createdKey, so inject it here\n if (entry.createdKey) {\n data[entry.createdKey] = new Date();\n }\n const missingKeys = entry.parentKeys.filter((k) => !data[k]);\n if (missingKeys.length > 0) {\n throw new Error(\n `Missing parent key(s) for subcollection create: ${missingKeys.join(\", \")}`,\n );\n }\n const parentIds = entry.parentKeys.map((k) => data[k] as string);\n const docKey = entry.documentKey ?? \"docId\";\n const docId = data[docKey] || generateFirestoreId();\n await entry.repo.set(...parentIds, docId, data);\n } else {\n await entry.repo.create(validation.data);\n }\n redirect(res, `${lb}/${entry.name}?flash=created`);\n } catch (err) {\n const createSchema2 = getMutableSchema(entry.schema, entry.createFields);\n const fields = zodToFields(createSchema2);\n const actionUrl = `${lb}/${entry.name}/create`;\n const formHtml = renderForm(fields, actionUrl, \"POST\", \"Create document\");\n sendHtml(\n res,\n renderFormPage(entry.name, formHtml, \"create\", null, lb, {\n type: \"error\",\n message: `Save error: ${(err as Error).message}`,\n }),\n 500,\n );\n }\n };\n\n // ── Edit form ─────────────────────────────────────────────────────────────\n const handleEditForm = async (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n ): Promise<void> => {\n const repoName = req.params[\"repoName\"];\n const docId = req.params[\"id\"];\n if (!repoName || !docId) {\n sendHtml(res, \"Bad request\", 400);\n return;\n }\n const entry = registry[repoName];\n if (!entry) {\n sendHtml(res, \"Repository not found\", 404);\n return;\n }\n\n let doc: Record<string, unknown> | null = null;\n try {\n doc = await fetchDocById(entry, docId);\n } catch (err) {\n sendHtml(res, `Error fetching document: ${(err as Error).message}`, 500);\n return;\n }\n\n if (!doc) {\n sendHtml(res, \"Document not found\", 404);\n return;\n }\n\n const prefilled = prefillFromDoc(doc, entry.schema);\n const mutableSchema = getMutableSchema(entry.schema, entry.mutableFields);\n const fields = applyPrefill(zodToFields(mutableSchema), prefilled);\n\n const lb = getLinkBase(req, basePath);\n const actionUrl = `${lb}/${entry.name}/${encodeURIComponent(docId)}/edit`;\n const formHtml = renderForm(fields, actionUrl, \"POST\", \"Save changes\");\n\n sendHtml(res, renderFormPage(entry.name, formHtml, \"edit\", docId, lb));\n };\n\n // ── Edit submit ───────────────────────────────────────────────────────────\n const handleEditSubmit = async (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n ): Promise<void> => {\n const repoName = req.params[\"repoName\"];\n const docId = req.params[\"id\"];\n if (!repoName || !docId) {\n sendHtml(res, \"Bad request\", 400);\n return;\n }\n const entry = registry[repoName];\n if (!entry) {\n sendHtml(res, \"Repository not found\", 404);\n return;\n }\n const lb = getLinkBase(req, basePath);\n const rawBody =\n (req.body as Record<string, string | string[] | undefined>) ?? {};\n const parsed = parseFormBody(rawBody, entry.schema);\n\n // Partial validation for updates (restricted to mutableFields)\n const mutableSchema = getMutableSchema(entry.schema, entry.mutableFields);\n const partialSchema = mutableSchema.partial();\n const validation = partialSchema.safeParse(parsed);\n\n if (!validation.success) {\n const prefilled = Object.fromEntries(\n Object.entries(rawBody).map(([k, v]) => [\n k,\n Array.isArray(v) ? v.join(\",\") : (v ?? \"\"),\n ]),\n );\n const fields = applyPrefill(zodToFields(mutableSchema), prefilled);\n const actionUrl = `${lb}/${entry.name}/${encodeURIComponent(docId)}/edit`;\n const formHtml = renderForm(fields, actionUrl, \"POST\", \"Save changes\");\n const errorMsg = validation.error.issues\n .map((e) => `${e.path.join(\".\")}: ${e.message}`)\n .join(\", \");\n sendHtml(\n res,\n renderFormPage(entry.name, formHtml, \"edit\", docId, lb, {\n type: \"error\",\n message: `Validation error: ${errorMsg}`,\n }),\n 422,\n );\n return;\n }\n\n try {\n // Fetch document to extract path args for subcollection repos\n const doc = await fetchDocById(entry, docId);\n const pathArgs = (doc && extractPathArgs(doc, entry.pathKey)) ?? [docId];\n await entry.repo.update(...pathArgs, validation.data);\n redirect(res, `${lb}/${entry.name}?flash=updated`);\n } catch (err) {\n const mutableSchema2 = getMutableSchema(\n entry.schema,\n entry.mutableFields,\n );\n const fields = zodToFields(mutableSchema2);\n const actionUrl = `${lb}/${entry.name}/${encodeURIComponent(docId)}/edit`;\n const formHtml = renderForm(fields, actionUrl, \"POST\", \"Save changes\");\n sendHtml(\n res,\n renderFormPage(entry.name, formHtml, \"edit\", docId, lb, {\n type: \"error\",\n message: `Save error: ${(err as Error).message}`,\n }),\n 500,\n );\n }\n };\n\n // ── Delete ────────────────────────────────────────────────────────────────\n const handleDelete = async (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n ): Promise<void> => {\n const repoName = req.params[\"repoName\"];\n const docId = req.params[\"id\"];\n if (!repoName || !docId) {\n sendHtml(res, \"Bad request\", 400);\n return;\n }\n const entry = registry[repoName];\n if (!entry) {\n sendHtml(res, \"Repository not found\", 404);\n return;\n }\n if (!entry.allowDelete) {\n sendHtml(res, \"Delete is not allowed for this repository\", 403);\n return;\n }\n const lb = getLinkBase(req, basePath);\n try {\n // Fetch document to extract path args for subcollection repos\n const doc = await fetchDocById(entry, docId);\n const pathArgs = (doc && extractPathArgs(doc, entry.pathKey)) ?? [docId];\n await entry.repo.delete(...pathArgs);\n redirect(res, `${lb}/${entry.name}?flash=deleted`);\n } catch (err) {\n sendHtml(res, `Delete error: ${(err as Error).message}`, 500);\n }\n };\n\n return {\n handleDashboard,\n handleList,\n handleCreateForm,\n handleCreateSubmit,\n handleEditForm,\n handleEditSubmit,\n handleDelete,\n };\n}\n","/**\n * Minimal zero-dependency HTTP router for Firebase Functions.\n * Compatible with any Express-like (req, res) handler.\n *\n * Supports:\n * - Named path parameters (e.g. \"/repos/:name/:id\")\n * - GET, POST, DELETE methods\n * - Global middleware (before each route)\n * - 404 / error fallbacks\n *\n * @example\n * ```typescript\n * import { MiniRouter } from \"@lpdjs/firestore-repo-service/servers/admin\";\n *\n * // Create router\n * const router = new MiniRouter();\n *\n * // Add global middleware (executed before every route)\n * router.use(async (req, res, next) => {\n * console.log(`${req.method} ${req.url}`);\n * await next();\n * });\n *\n * // Auth middleware\n * router.use((req, res, next) => {\n * if (!req.headers?.authorization) {\n * res.status(401).send(\"Unauthorized\");\n * return;\n * }\n * next();\n * });\n *\n * // Define routes with path parameters\n * router.get(\"/users\", async (req, res) => {\n * res.json({ users: await getAllUsers() });\n * });\n *\n * router.get(\"/users/:id\", async (req, res) => {\n * const user = await getUser(req.params.id); // Access path params\n * if (!user) {\n * res.status(404).send(\"User not found\");\n * return;\n * }\n * res.json(user);\n * });\n *\n * router.post(\"/users\", async (req, res) => {\n * const user = await createUser(req.body);\n * res.status(201).json(user);\n * });\n *\n * router.delete(\"/users/:id\", async (req, res) => {\n * await deleteUser(req.params.id);\n * res.status(204).end();\n * });\n *\n * // Custom 404 handler\n * router.onNotFound((req, res) => {\n * res.status(404).json({ error: \"Route not found\", path: req.url });\n * });\n *\n * // Custom error handler\n * router.onError((err, req, res) => {\n * console.error(\"Error:\", err);\n * res.status(500).json({ error: \"Internal server error\" });\n * });\n *\n * // Use with Firebase Functions\n * export const api = onRequest(async (req, res) => {\n * await router.handle(req, res);\n * });\n * ```\n */\n\nexport type AnyReq = {\n method?: string;\n url?: string;\n /** Express originalUrl — preserved before any router stripping, contains the full path including the Firebase Functions prefix */\n originalUrl?: string;\n path?: string;\n headers?: Record<string, string | string[] | undefined>;\n body?: unknown;\n query?: Record<string, string | string[] | undefined>;\n};\n\nexport type AnyRes = {\n status: (code: number) => AnyRes;\n set: (key: string, value: string) => AnyRes;\n send: (body: string) => void;\n json: (body: unknown) => void;\n end: () => void;\n};\n\nexport type RouteParams = Record<string, string>;\n\nexport type RouteHandler = (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n) => void | Promise<void>;\n\nexport type Middleware = (\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n next: () => void | Promise<void>,\n) => void | Promise<void>;\n\n// ---------------------------------------------------------------------------\n// Route matching\n// ---------------------------------------------------------------------------\n\ninterface CompiledRoute {\n method: string;\n pattern: RegExp;\n paramNames: string[];\n handler: RouteHandler;\n}\n\nfunction compilePath(path: string): { pattern: RegExp; paramNames: string[] } {\n const paramNames: string[] = [];\n const src = path\n .replace(/[.*+?^${}()|[\\]\\\\]/g, (c) => (c === \":\" ? c : `\\\\${c}`))\n .replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_match, name: string) => {\n paramNames.push(name);\n return \"([^/]+)\";\n });\n\n return { pattern: new RegExp(`^${src}$`), paramNames };\n}\n\nfunction extractPath(req: AnyReq): string {\n const raw = req.path ?? req.url ?? \"/\";\n const idx = raw.indexOf(\"?\");\n return idx === -1 ? raw : raw.slice(0, idx);\n}\n\n// ---------------------------------------------------------------------------\n// Router class\n// ---------------------------------------------------------------------------\n\nexport class MiniRouter {\n private routes: CompiledRoute[] = [];\n private middlewares: Middleware[] = [];\n private notFoundHandler: RouteHandler = (_req, res) => {\n res.status(404).send(\"Not Found\");\n };\n private errorHandler: (err: unknown, req: AnyReq, res: AnyRes) => void = (\n err,\n _req,\n res,\n ) => {\n console.error(\"[MiniRouter]\", err);\n res.status(500).send(\"Internal Server Error\");\n };\n\n // ── Route registration ────────────────────────────────────────────────────\n\n use(middleware: Middleware): this {\n this.middlewares.push(middleware);\n return this;\n }\n\n get(path: string, handler: RouteHandler): this {\n return this.addRoute(\"GET\", path, handler);\n }\n\n post(path: string, handler: RouteHandler): this {\n return this.addRoute(\"POST\", path, handler);\n }\n\n put(path: string, handler: RouteHandler): this {\n return this.addRoute(\"PUT\", path, handler);\n }\n\n patch(path: string, handler: RouteHandler): this {\n return this.addRoute(\"PATCH\", path, handler);\n }\n\n delete(path: string, handler: RouteHandler): this {\n return this.addRoute(\"DELETE\", path, handler);\n }\n\n onNotFound(handler: RouteHandler): this {\n this.notFoundHandler = handler;\n return this;\n }\n\n onError(handler: (err: unknown, req: AnyReq, res: AnyRes) => void): this {\n this.errorHandler = handler;\n return this;\n }\n\n private addRoute(method: string, path: string, handler: RouteHandler): this {\n const { pattern, paramNames } = compilePath(path);\n this.routes.push({\n method: method.toUpperCase(),\n pattern,\n paramNames,\n handler,\n });\n return this;\n }\n\n // ── Dispatch ──────────────────────────────────────────────────────────────\n\n async handle(req: AnyReq, res: AnyRes): Promise<void> {\n const method = (req.method ?? \"GET\").toUpperCase();\n const path = extractPath(req);\n\n // Find matching route\n let matchedRoute: CompiledRoute | null = null;\n let params: RouteParams = {};\n\n for (const route of this.routes) {\n if (route.method !== method) continue;\n const m = path.match(route.pattern);\n if (m) {\n matchedRoute = route;\n params = {};\n route.paramNames.forEach((name, i) => {\n params[name] = decodeURIComponent(m[i + 1] ?? \"\");\n });\n break;\n }\n }\n\n const enrichedReq = Object.assign(req, { params });\n\n // Run middleware chain → then handler\n const handler = matchedRoute ? matchedRoute.handler : this.notFoundHandler;\n\n try {\n await this.runMiddlewareChain(enrichedReq, res, handler);\n } catch (err) {\n this.errorHandler(err, req, res);\n }\n }\n\n private async runMiddlewareChain(\n req: AnyReq & { params: RouteParams },\n res: AnyRes,\n finalHandler: RouteHandler,\n ): Promise<void> {\n let index = 0;\n\n const next = async (): Promise<void> => {\n if (index < this.middlewares.length) {\n const mw = this.middlewares[index++]!;\n await mw(req, res, next);\n } else {\n await finalHandler(req, res);\n }\n };\n\n await next();\n }\n}\n","/**\n * @module servers/admin\n *\n * Creates a static ORM admin interface served as a Firebase HTTPS function.\n *\n * Features:\n * - Dashboard listing all registered repositories\n * - Document list with cursor-based pagination\n * - Create / Edit / Delete forms generated from Zod schemas\n * - Forms map **exactly** to the repository model type\n * - Zero JavaScript framework — plain HTML + inline CSS + vanilla JS\n * - Body parsing for `application/x-www-form-urlencoded` (default HTML forms)\n * and `application/json` (API clients)\n *\n * @example\n * ```ts\n * import * as functions from \"firebase-functions\";\n * import { z } from \"zod\";\n * import { createAdminServer } from \"@lpdjs/firestore-repo-service/servers/admin\";\n *\n * const postSchema = z.object({\n * title: z.string().min(1),\n * content: z.string(),\n * status: z.enum([\"draft\", \"published\"]),\n * authorId: z.string(),\n * });\n *\n * export const adminApp = functions.https.onRequest(\n * createAdminServer({\n * basePath: \"/admin\",\n * repos: {\n * posts: { repo: repos.posts, schema: postSchema, path: \"posts\" },\n * },\n * })\n * );\n * ```\n */\n\nimport type { z } from \"zod\";\nimport type { ConfiguredRepository } from \"../../repositories/types\";\nimport type { FieldPath, RepositoryConfig } from \"../../shared/types\";\nimport type { FieldRole } from \"../crud/types\";\nimport type { HttpRequest, HttpResponse } from \"../http-types\";\nimport type { AdminRepoEntry, RepoRegistry } from \"./handlers\";\nimport { createAdminHandlers } from \"./handlers\";\nimport type { RelationalFieldMeta } from \"./renderer\";\nimport { type Middleware, MiniRouter } from \"./router\";\n\n// ---------------------------------------------------------------------------\n// Public option types\n// ---------------------------------------------------------------------------\n\n/**\n * Extracts the model type `T` from a `ConfiguredRepository`.\n * @internal\n */\ntype RepoModelType<TRepo> =\n TRepo extends ConfiguredRepository<\n RepositoryConfig<infer T, any, any, any, any, any, any, any, any, any>\n >\n ? T\n : never;\n\n/**\n * Configuration for a single repository in the admin server.\n *\n * @template TRepo - The `ConfiguredRepository` type; used to derive typed field names.\n *\n * If the repository was created with `createRepositoryConfig(schema)(config)`,\n * the `schema` field is optional — it is auto-detected from the repo.\n * Otherwise, pass `schema` explicitly.\n *\n * @example\n * ```ts\n * posts: {\n * repo: repos.posts,\n * fieldsConfig: {\n * title: [\"create\", \"mutable\", \"filterable\"],\n * content: [\"create\", \"mutable\"],\n * status: [\"create\", \"filterable\"],\n * },\n * allowDelete: true,\n * }\n * ```\n */\nexport interface AdminRepoConfig<\n TRepo extends ConfiguredRepository<any> = ConfiguredRepository<any>,\n> {\n /** The configured repository instance. Drives type inference for all other fields. */\n repo: TRepo;\n /**\n * Zod schema — optional when the repo was created with `createRepositoryConfig(schema)`.\n * Pass explicitly for repos created with the legacy `createRepositoryConfig<T>()` form.\n */\n schema?: z.ZodObject<any>;\n /** Firestore collection path (for display only) */\n path: string;\n /** Key used to identify documents (default: \"docId\") */\n documentKey?: string;\n /** Columns to display in the list view (default: all schema keys) */\n listColumns?: string[];\n /** Number of documents per page in the list view (default: 25) */\n pageSize?: number;\n /**\n * Per-field role configuration.\n * Each key is a model field (with autocomplete); the value is an array of roles.\n *\n * Roles:\n * - `\"create\"` — field is shown in the create form\n * - `\"mutable\"` — field is shown in the edit form\n * - `\"filterable\"` — field is shown in the filter bar\n *\n * If omitted, all schema fields are shown in all contexts.\n *\n * @example\n * ```ts\n * fieldsConfig: {\n * title: [\"create\", \"mutable\", \"filterable\"],\n * content: [\"create\", \"mutable\"],\n * status: [\"create\", \"filterable\"],\n * }\n * ```\n */\n fieldsConfig?: Partial<Record<FieldPath<RepoModelType<TRepo>>, readonly FieldRole[]>>;\n /**\n * Whether to show the delete button in the list view.\n * Default: false — delete is disabled unless explicitly set to true.\n */\n allowDelete?: boolean;\n /**\n * Relational action columns appended to the list table.\n * Each entry adds a dedicated button that navigates to the linked repository.\n *\n * - **type \"one\"** (e.g. `userId` on a post) → button links to the target\n * document edit page: `/{targetRepo}/{value}/edit`\n * - **type \"many\"** (e.g. `docId` on a user) → button links to the target\n * repo list filtered by value: `/{targetRepo}?fv_{targetKey}={value}`\n *\n * @example\n * ```ts\n * users: {\n * repo: repos.users,\n * relationalFields: [\n * { key: \"docId\", column: \"Posts\" }, // many → list of posts by this user\n * ]\n * }\n * posts: {\n * repo: repos.posts,\n * relationalFields: [\n * { key: \"userId\", column: \"Author\" }, // one → edit page of the user\n * ]\n * }\n * ```\n */\n relationalFields?: {\n key: keyof RepoModelType<TRepo> & string;\n column: string;\n }[];\n}\n\n/**\n * HTTP Basic Auth configuration.\n * The browser will show a native login dialog.\n */\nexport interface BasicAuthConfig {\n type: \"basic\";\n /** Realm displayed in the browser login dialog */\n realm?: string;\n username: string;\n password: string;\n}\n\n/**\n * Options for `createAdminServer`.\n *\n * Made generic so TypeScript can infer the model type of each repo entry\n * and provide autocomplete + type-checking on `fieldsConfig`.\n *\n * @template TRepos - Shape of the repos map (inferred automatically at the call site)\n */\nexport interface AdminServerOptions<\n TRepos extends Record<string, ConfiguredRepository<any>> = Record<\n string,\n ConfiguredRepository<any>\n >,\n> {\n /**\n * Base URL path of the function (e.g. \"/admin\").\n * Must match the path where the Firebase Function is mounted.\n * Default: \"/\"\n */\n basePath?: string;\n\n /**\n * Repository entries keyed by a display name.\n * TypeScript infers the model type from each `repo` field,\n * so `fieldsConfig` keys are typed to that model's field paths.\n *\n * @example\n * ```ts\n * repos: {\n * posts: {\n * repo: repos.posts,\n * fieldsConfig: {\n * title: [\"create\", \"mutable\", \"filterable\"],\n * content: [\"create\", \"mutable\"],\n * status: [\"create\", \"filterable\"],\n * },\n * },\n * }\n * ```\n */\n repos: { [K in keyof TRepos]: AdminRepoConfig<TRepos[K]> };\n\n /** Whether to parse URL-encoded bodies. Default: true. */\n parseBody?: boolean;\n\n /**\n * Authentication guard executed before every request.\n * - Pass a `BasicAuthConfig` to enable HTTP Basic Auth.\n * - Pass a `Middleware` function for custom auth logic.\n */\n auth?: BasicAuthConfig | Middleware;\n\n /**\n * Additional middleware functions executed after auth, before route handlers.\n */\n middleware?: Middleware[];\n\n /**\n * Options forwarded to `onRequest()` from `firebase-functions/v2/https`.\n * Stored on the returned handler as `.httpsOptions` for easy access.\n *\n * @example\n * ```ts\n * const handler = createAdminServer({ httpsOptions: { invoker: \"public\" }, ... });\n * export const admin = onRequest(handler.httpsOptions!, handler);\n * ```\n */\n httpsOptions?: Record<string, unknown>;\n}\n\n// ---------------------------------------------------------------------------\n// Body parser (replaces express.urlencoded in Firebase Functions context)\n// ---------------------------------------------------------------------------\n\n/** Eagerly reads the raw request body as a string */\nasync function readRawBody(req: HttpRequest): Promise<string> {\n if (typeof (req as any).rawBody === \"string\")\n return (req as any).rawBody as string;\n if (Buffer.isBuffer((req as any).rawBody))\n return ((req as any).rawBody as Buffer).toString(\"utf8\");\n // Firebase Functions v2 / Cloud Run: body may already be parsed\n return \"\";\n}\n\nfunction parseUrlEncoded(body: string): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {};\n if (!body) return result;\n for (const pair of body.split(\"&\")) {\n const idx = pair.indexOf(\"=\");\n if (idx === -1) continue;\n const key = decodeURIComponent(pair.slice(0, idx).replace(/\\+/g, \" \"));\n const val = decodeURIComponent(pair.slice(idx + 1).replace(/\\+/g, \" \"));\n const existing = result[key];\n if (existing === undefined) {\n result[key] = val;\n } else if (Array.isArray(existing)) {\n existing.push(val);\n } else {\n result[key] = [existing, val];\n }\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Creates an Express-compatible request handler for the admin ORM UI.\n * Generates a complete admin interface with dashboard, lists, and CRUD forms.\n *\n * @template TRepos - Shape of the repos map (inferred automatically)\n * @param options - Admin server configuration\n * @returns Express-compatible request handler for Firebase Functions\n *\n * @example\n * ```typescript\n * // Basic admin server\n * import { onRequest } from \"firebase-functions/https\";\n * import { createAdminServer } from \"@lpdjs/firestore-repo-service/servers/admin\";\n *\n * export const admin = onRequest(\n * createAdminServer({\n * basePath: \"/admin\",\n * repos: {\n * users: {\n * repo: repos.users,\n * path: \"users\",\n * },\n * posts: {\n * repo: repos.posts,\n * path: \"posts\",\n * },\n * },\n * })\n * );\n *\n * // With HTTP Basic Auth\n * export const admin = onRequest(\n * createAdminServer({\n * basePath: \"/admin\",\n * auth: {\n * type: \"basic\",\n * realm: \"Admin Area\",\n * username: \"admin\",\n * password: process.env.ADMIN_PASSWORD!,\n * },\n * repos: { ... },\n * })\n * );\n *\n * // With custom auth middleware\n * export const admin = onRequest(\n * createAdminServer({\n * auth: async (req, res, next) => {\n * const token = req.headers?.authorization?.replace(\"Bearer \", \"\");\n * if (!token || !(await verifyToken(token))) {\n * res.status(401).send(\"Unauthorized\");\n * return;\n * }\n * next();\n * },\n * repos: { ... },\n * })\n * );\n *\n * // Full configuration with all options\n * export const admin = onRequest(\n * createAdminServer({\n * basePath: \"/admin\",\n * parseBody: true, // Parse URL-encoded bodies\n * auth: { type: \"basic\", username: \"admin\", password: \"secret\" },\n * middleware: [loggingMiddleware], // Additional middleware\n * repos: {\n * posts: {\n * repo: repos.posts,\n * path: \"posts\",\n * documentKey: \"docId\", // Field used as document ID\n * listColumns: [\"title\", \"status\", \"createdAt\"], // Columns in list\n * pageSize: 25, // Items per page in list\n * fieldsConfig: {\n * title: [\"create\", \"mutable\", \"filterable\"],\n * content: [\"create\", \"mutable\"],\n * status: [\"create\", \"mutable\", \"filterable\"],\n * userId: [\"filterable\"],\n * },\n * allowDelete: true, // Enable delete button\n * relationalFields: [ // Relation navigation buttons\n * { key: \"userId\", column: \"Author\" }, // Link to user\n * { key: \"docId\", column: \"Comments\" }, // Link to comments list\n * ],\n * },\n * users: {\n * repo: repos.users,\n * path: \"users\",\n * fieldsConfig: {\n * name: [\"create\", \"mutable\"],\n * email: [\"create\", \"mutable\", \"filterable\"],\n * isActive: [\"mutable\", \"filterable\"],\n * },\n * allowDelete: false,\n * relationalFields: [\n * { key: \"docId\", column: \"Posts\" },\n * ],\n * },\n * },\n * })\n * );\n *\n * // Routes generated automatically:\n * // GET /admin/ → Dashboard (list of repos)\n * // GET /admin/:repo → Document list with pagination\n * // GET /admin/:repo/create → Create form\n * // POST /admin/:repo/create → Submit create\n * // GET /admin/:repo/:id/edit → Edit form\n * // POST /admin/:repo/:id/edit → Submit edit\n * // POST /admin/:repo/:id/delete → Delete document\n * ```\n */\nexport function createAdminServer<\n TRepos extends Record<string, ConfiguredRepository<any>>,\n>(\n options: AdminServerOptions<TRepos>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): ((req: any, res: any) => Promise<void>) & { httpsOptions?: Record<string, unknown> } {\n const {\n basePath = \"/\",\n repos,\n parseBody = true,\n auth,\n middleware: extraMiddleware = [],\n httpsOptions,\n } = options;\n\n // Normalise basePath: no trailing slash\n const base = basePath === \"/\" ? \"\" : basePath.replace(/\\/$/, \"\");\n\n // Build the registry\n const registry: RepoRegistry = {};\n for (const [name, cfg] of Object.entries(repos)) {\n // Schema resolution: explicit cfg.schema > embedded in repo (createRepositoryConfig(schema))\n const resolvedSchema = cfg.schema ?? (cfg.repo as any).schema ?? null;\n if (!resolvedSchema) {\n throw new Error(\n `[createAdminServer] Repository \"${name}\" has no Zod schema. ` +\n `Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`,\n );\n }\n // Resolve fieldsConfig → separate arrays for runtime\n let filterableFields: string[] | undefined;\n let mutableFields: string[] | undefined;\n let createFields: string[] | undefined;\n if (cfg.fieldsConfig) {\n const fc = cfg.fieldsConfig as Record<string, readonly string[]>;\n filterableFields = [];\n mutableFields = [];\n createFields = [];\n for (const [field, roles] of Object.entries(fc)) {\n for (const role of roles) {\n if (role === \"filterable\") filterableFields.push(field);\n else if (role === \"mutable\") mutableFields.push(field);\n else if (role === \"create\") createFields.push(field);\n }\n }\n if (filterableFields.length === 0) filterableFields = undefined;\n if (mutableFields.length === 0) mutableFields = undefined;\n if (createFields.length === 0) createFields = undefined;\n }\n\n // For collection-group repos, ensure parentKeys are included in createFields\n // so the form/validation allows the user to provide them.\n const parentKeys = (() => {\n const pk = (cfg.repo as any)._parentKeys as string[] | undefined;\n return pk && pk.length > 0 ? pk : undefined;\n })();\n if (parentKeys && createFields) {\n for (const pk of parentKeys) {\n if (!createFields.includes(pk)) createFields.push(pk);\n }\n }\n\n const entry: AdminRepoEntry = {\n name,\n path: cfg.path,\n repo: cfg.repo,\n schema: resolvedSchema,\n documentKey: cfg.documentKey ?? \"docId\",\n pathKey: (cfg.repo as any)._pathKey ?? undefined,\n isGroup: !!(cfg.repo as any)._isGroup,\n parentKeys,\n createdKey: (cfg.repo as any)._createdKey ?? undefined,\n listColumns: cfg.listColumns,\n pageSize: cfg.pageSize,\n filterableFields,\n mutableFields,\n createFields,\n allowDelete: cfg.allowDelete ?? false,\n relationalMeta: (() => {\n if (!cfg.relationalFields || cfg.relationalFields.length === 0)\n return undefined;\n const repoRelKeys = (cfg.repo as any).relationalKeys ?? {};\n const meta: RelationalFieldMeta[] = [];\n for (const entry of cfg.relationalFields) {\n const rel = repoRelKeys[entry.key];\n if (rel) {\n meta.push({\n key: entry.key,\n column: entry.column,\n targetRepo: String(rel.repo),\n targetKey: String(rel.key),\n type: rel.type as \"one\" | \"many\",\n });\n }\n }\n return meta.length > 0 ? meta : undefined;\n })(),\n };\n registry[name] = entry;\n }\n\n const handlers = createAdminHandlers(registry, base);\n\n // ── Router ─────────────────────────────────────────────────────────────\n const router = new MiniRouter();\n\n // ── 1. Body-parsing middleware ──────────────────────────────────────────\n if (parseBody) {\n router.use(async (req, _res, next) => {\n const r = req as unknown as HttpRequest;\n const contentType = String(r.headers?.[\"content-type\"] ?? \"\");\n if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n const raw = await readRawBody(r);\n (req as any).body = parseUrlEncoded(raw);\n } else if (\n contentType.includes(\"application/json\") &&\n typeof r.body === \"string\"\n ) {\n try {\n (req as any).body = JSON.parse(r.body as string);\n } catch {\n /* keep as string */\n }\n }\n await next();\n });\n }\n\n // ── 2. Auth middleware ──────────────────────────────────────────────────\n if (auth) {\n if (typeof auth === \"function\") {\n // Custom middleware\n router.use(auth);\n } else {\n // HTTP Basic Auth\n const realm = auth.realm ?? \"Admin\";\n const expected =\n \"Basic \" +\n Buffer.from(`${auth.username}:${auth.password}`).toString(\"base64\");\n router.use((req, res, next) => {\n const authorization = (req as any).headers?.[\"authorization\"] ?? \"\";\n if (authorization !== expected) {\n res\n .status(401)\n .set(\"WWW-Authenticate\", `Basic realm=\"${realm}\"`)\n .set(\"Content-Type\", \"text/plain\")\n .send(\"Unauthorized\");\n return;\n }\n next();\n });\n }\n }\n\n // ── 3. Extra user middleware ────────────────────────────────────────────\n for (const mw of extraMiddleware) {\n router.use(mw);\n }\n\n // ── 4. Routes ─────────────────────────────────────────────────────────────\n router.get(`${base}/`, handlers.handleDashboard);\n router.get(`${base}`, handlers.handleDashboard);\n\n router.get(`${base}/:repoName`, handlers.handleList);\n\n router.get(`${base}/:repoName/create`, handlers.handleCreateForm);\n router.post(`${base}/:repoName/create`, handlers.handleCreateSubmit as any);\n\n router.get(`${base}/:repoName/:id/edit`, handlers.handleEditForm as any);\n router.post(`${base}/:repoName/:id/edit`, handlers.handleEditSubmit as any);\n\n router.post(`${base}/:repoName/:id/delete`, handlers.handleDelete as any);\n\n // ── Request handler ─────────────────────────────────────────────────────\n const handler = async (req: HttpRequest, res: HttpResponse): Promise<void> => {\n await router.handle(req as any, res as any);\n };\n if (httpsOptions) (handler as any).httpsOptions = httpsOptions;\n return handler as ((req: any, res: any) => Promise<void>) & { httpsOptions?: Record<string, unknown> };\n}\n\n// Re-exports for convenience\nexport type { AdminRepoEntry, RepoRegistry } from \"./handlers\";\nexport { MiniRouter } from \"./router\";\nexport type { Middleware, RouteHandler } from \"./router\";\n"]}