@kyro-cms/core 0.12.46 → 0.12.47

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.
@@ -121,7 +121,7 @@
121
121
  ]))`;continue}}if(r.s&&s[p]==="."){n+=i?`${s[p]}\r
122
122
  `:`[${s[p]}\r
123
123
  ]`;continue}n+=s[p],s[p]==="\\"?o=true:i&&s[p]==="]"?i=false:!i&&s[p]==="["&&(i=true);}try{new RegExp(n);}catch{return console.warn(`Could not convert regex pattern at ${e.currentPath.join("/")} to a flag-independent form! Falling back to the flag-ignorant source`),t.source}return n}function Bc(t,e){if(e.target==="openAi"&&console.warn("Warning: OpenAI may not support records in schemas! Try an array of key-value pairs instead."),e.target==="openApi3"&&t.keyType?._def.typeName===exports.ia.ZodEnum)return {type:"object",required:t.keyType._def.values,properties:t.keyType._def.values.reduce((s,n)=>({...s,[n]:se(t.valueType._def,{...e,currentPath:[...e.currentPath,"properties",n]})??Le(e)}),{}),additionalProperties:e.rejectedAdditionalProperties};let r={type:"object",additionalProperties:se(t.valueType._def,{...e,currentPath:[...e.currentPath,"additionalProperties"]})??e.allowedAdditionalProperties};if(e.target==="openApi3")return r;if(t.keyType?._def.typeName===exports.ia.ZodString&&t.keyType._def.checks?.length){let{type:s,...n}=$c(t.keyType._def,e);return {...r,propertyNames:n}}else {if(t.keyType?._def.typeName===exports.ia.ZodEnum)return {...r,propertyNames:{enum:t.keyType._def.values}};if(t.keyType?._def.typeName===exports.ia.ZodBranded&&t.keyType._def.type._def.typeName===exports.ia.ZodString&&t.keyType._def.type._def.checks?.length){let{type:s,...n}=Lc(t.keyType._def,e);return {...r,propertyNames:n}}}return r}function d_(t,e){if(e.mapStrategy==="record")return Bc(t,e);let r=se(t.keyType._def,{...e,currentPath:[...e.currentPath,"items","items","0"]})||Le(e),s=se(t.valueType._def,{...e,currentPath:[...e.currentPath,"items","items","1"]})||Le(e);return {type:"array",maxItems:125,items:{type:"array",items:[r,s],minItems:2,maxItems:2}}}chunkBUNLC3II_cjs.h();function p_(t){let e=t.values,s=Object.keys(t.values).filter(o=>typeof e[e[o]]!="number").map(o=>e[o]),n=Array.from(new Set(s.map(o=>typeof o)));return {type:n.length===1?n[0]==="string"?"string":"number":["string","number"],enum:s}}chunkBUNLC3II_cjs.h();function f_(t){return t.target==="openAi"?void 0:{not:Le({...t,currentPath:[...t.currentPath,"not"]})}}chunkBUNLC3II_cjs.h();function m_(t){return t.target==="openApi3"?{enum:["null"],nullable:true}:{type:"null"}}chunkBUNLC3II_cjs.h();chunkBUNLC3II_cjs.h();var ua={ZodString:"string",ZodNumber:"number",ZodBigInt:"integer",ZodBoolean:"boolean",ZodNull:"null"};function g_(t,e){if(e.target==="openApi3")return h_(t,e);let r=t.options instanceof Map?Array.from(t.options.values()):t.options;if(r.every(s=>s._def.typeName in ua&&(!s._def.checks||!s._def.checks.length))){let s=r.reduce((n,o)=>{let i=ua[o._def.typeName];return i&&!n.includes(i)?[...n,i]:n},[]);return {type:s.length>1?s:s[0]}}else if(r.every(s=>s._def.typeName==="ZodLiteral"&&!s.description)){let s=r.reduce((n,o)=>{let i=typeof o._def.value;switch(i){case "string":case "number":case "boolean":return [...n,i];case "bigint":return [...n,"integer"];case "object":if(o._def.value===null)return [...n,"null"];default:return n}},[]);if(s.length===r.length){let n=s.filter((o,i,c)=>c.indexOf(o)===i);return {type:n.length>1?n:n[0],enum:r.reduce((o,i)=>o.includes(i._def.value)?o:[...o,i._def.value],[])}}}else if(r.every(s=>s._def.typeName==="ZodEnum"))return {type:"string",enum:r.reduce((s,n)=>[...s,...n._def.values.filter(o=>!s.includes(o))],[])};return h_(t,e)}var h_=(t,e)=>{let r=(t.options instanceof Map?Array.from(t.options.values()):t.options).map((s,n)=>se(s._def,{...e,currentPath:[...e.currentPath,"anyOf",`${n}`]})).filter(s=>!!s&&(!e.strictUnions||typeof s=="object"&&Object.keys(s).length>0));return r.length?{anyOf:r}:void 0};function y_(t,e){if(["ZodString","ZodNumber","ZodBigInt","ZodBoolean","ZodNull"].includes(t.innerType._def.typeName)&&(!t.innerType._def.checks||!t.innerType._def.checks.length))return e.target==="openApi3"?{type:ua[t.innerType._def.typeName],nullable:true}:{type:[ua[t.innerType._def.typeName],"null"]};if(e.target==="openApi3"){let s=se(t.innerType._def,{...e,currentPath:[...e.currentPath]});return s&&"$ref"in s?{allOf:[s],nullable:true}:s&&{...s,nullable:true}}let r=se(t.innerType._def,{...e,currentPath:[...e.currentPath,"anyOf","0"]});return r&&{anyOf:[r,{type:"null"}]}}chunkBUNLC3II_cjs.h();function x_(t,e){let r={type:"number"};if(!t.checks)return r;for(let s of t.checks)switch(s.kind){case "int":r.type="integer",Pd(r,"type",s.message,e);break;case "min":e.target==="jsonSchema7"?s.inclusive?me(r,"minimum",s.value,s.message,e):me(r,"exclusiveMinimum",s.value,s.message,e):(s.inclusive||(r.exclusiveMinimum=true),me(r,"minimum",s.value,s.message,e));break;case "max":e.target==="jsonSchema7"?s.inclusive?me(r,"maximum",s.value,s.message,e):me(r,"exclusiveMaximum",s.value,s.message,e):(s.inclusive||(r.exclusiveMaximum=true),me(r,"maximum",s.value,s.message,e));break;case "multipleOf":me(r,"multipleOf",s.value,s.message,e);break}return r}chunkBUNLC3II_cjs.h();function w_(t,e){let r=e.target==="openAi",s={type:"object",properties:{}},n=[],o=t.shape();for(let c in o){let p=o[c];if(p===void 0||p._def===void 0)continue;let d=MN(p);d&&r&&(p._def.typeName==="ZodOptional"&&(p=p._def.innerType),p.isNullable()||(p=p.nullable()),d=false);let x=se(p._def,{...e,currentPath:[...e.currentPath,"properties",c],propertyPath:[...e.currentPath,"properties",c]});x!==void 0&&(s.properties[c]=x,d||n.push(c));}n.length&&(s.required=n);let i=NN(t,e);return i!==void 0&&(s.additionalProperties=i),s}function NN(t,e){if(t.catchall._def.typeName!=="ZodNever")return se(t.catchall._def,{...e,currentPath:[...e.currentPath,"additionalProperties"]});switch(t.unknownKeys){case "passthrough":return e.allowedAdditionalProperties;case "strict":return e.rejectedAdditionalProperties;case "strip":return e.removeAdditionalStrategy==="strict"?e.allowedAdditionalProperties:e.rejectedAdditionalProperties}}function MN(t){try{return t.isOptional()}catch{return true}}chunkBUNLC3II_cjs.h();var __=(t,e)=>{if(e.currentPath.toString()===e.propertyPath?.toString())return se(t.innerType._def,e);let r=se(t.innerType._def,{...e,currentPath:[...e.currentPath,"anyOf","1"]});return r?{anyOf:[{not:Le(e)},r]}:Le(e)};chunkBUNLC3II_cjs.h();var v_=(t,e)=>{if(e.pipeStrategy==="input")return se(t.in._def,e);if(e.pipeStrategy==="output")return se(t.out._def,e);let r=se(t.in._def,{...e,currentPath:[...e.currentPath,"allOf","0"]}),s=se(t.out._def,{...e,currentPath:[...e.currentPath,"allOf",r?"1":"0"]});return {allOf:[r,s].filter(n=>n!==void 0)}};chunkBUNLC3II_cjs.h();function b_(t,e){return se(t.type._def,e)}chunkBUNLC3II_cjs.h();function S_(t,e){let s={type:"array",uniqueItems:true,items:se(t.valueType._def,{...e,currentPath:[...e.currentPath,"items"]})};return t.minSize&&me(s,"minItems",t.minSize.value,t.minSize.message,e),t.maxSize&&me(s,"maxItems",t.maxSize.value,t.maxSize.message,e),s}chunkBUNLC3II_cjs.h();function A_(t,e){return t.rest?{type:"array",minItems:t.items.length,items:t.items.map((r,s)=>se(r._def,{...e,currentPath:[...e.currentPath,"items",`${s}`]})).reduce((r,s)=>s===void 0?r:[...r,s],[]),additionalItems:se(t.rest._def,{...e,currentPath:[...e.currentPath,"additionalItems"]})}:{type:"array",minItems:t.items.length,maxItems:t.items.length,items:t.items.map((r,s)=>se(r._def,{...e,currentPath:[...e.currentPath,"items",`${s}`]})).reduce((r,s)=>s===void 0?r:[...r,s],[])}}chunkBUNLC3II_cjs.h();function R_(t){return {not:Le(t)}}chunkBUNLC3II_cjs.h();function E_(t){return Le(t)}chunkBUNLC3II_cjs.h();var C_=(t,e)=>se(t.innerType._def,e);var k_=(t,e,r)=>{switch(e){case exports.ia.ZodString:return $c(t,r);case exports.ia.ZodNumber:return x_(t,r);case exports.ia.ZodObject:return w_(t,r);case exports.ia.ZodBigInt:return r_(t,r);case exports.ia.ZodBoolean:return s_();case exports.ia.ZodDate:return Md(t,r);case exports.ia.ZodUndefined:return R_(r);case exports.ia.ZodNull:return m_(r);case exports.ia.ZodArray:return t_(t,r);case exports.ia.ZodUnion:case exports.ia.ZodDiscriminatedUnion:return g_(t,r);case exports.ia.ZodIntersection:return c_(t,r);case exports.ia.ZodTuple:return A_(t,r);case exports.ia.ZodRecord:return Bc(t,r);case exports.ia.ZodLiteral:return u_(t,r);case exports.ia.ZodEnum:return i_(t);case exports.ia.ZodNativeEnum:return p_(t);case exports.ia.ZodNullable:return y_(t,r);case exports.ia.ZodOptional:return __(t,r);case exports.ia.ZodMap:return d_(t,r);case exports.ia.ZodSet:return S_(t,r);case exports.ia.ZodLazy:return ()=>t.getter()._def;case exports.ia.ZodPromise:return b_(t,r);case exports.ia.ZodNaN:case exports.ia.ZodNever:return f_(r);case exports.ia.ZodEffects:return a_(t,r);case exports.ia.ZodAny:return Le(r);case exports.ia.ZodUnknown:return E_(r);case exports.ia.ZodDefault:return o_(t,r);case exports.ia.ZodBranded:return Lc(t,r);case exports.ia.ZodReadonly:return C_(t,r);case exports.ia.ZodCatch:return n_(t,r);case exports.ia.ZodPipeline:return v_(t,r);case exports.ia.ZodFunction:case exports.ia.ZodVoid:case exports.ia.ZodSymbol:return;default:return (s=>{})()}};function se(t,e,r=false){let s=e.seen.get(t);if(e.override){let c=e.override?.(t,e,s,r);if(c!==zw)return c}if(s&&!r){let c=jN(s,e);if(c!==void 0)return c}let n={def:t,path:e.currentPath,jsonSchema:void 0};e.seen.set(t,n);let o=k_(t,t.typeName,e),i=typeof o=="function"?se(o(),e):o;if(i&&UN(t,e,i),e.postProcess){let c=e.postProcess(i,t,e);return n.jsonSchema=i,c}return n.jsonSchema=i,i}var jN=(t,e)=>{switch(e.$refStrategy){case "root":return {$ref:t.path.join("/")};case "relative":return {$ref:Pc(e.currentPath,t.path)};case "none":case "seen":return t.path.length<e.currentPath.length&&t.path.every((r,s)=>e.currentPath[s]===r)?(console.warn(`Recursive reference detected at ${e.currentPath.join("/")}! Defaulting to any`),Le(e)):e.$refStrategy==="seen"?Le(e):void 0}},UN=(t,e,r)=>(t.description&&(r.description=t.description,e.markdownDescription&&(r.markdownDescription=t.description)),r);chunkBUNLC3II_cjs.h();chunkBUNLC3II_cjs.h();var to=(t,e)=>{let r=Vw(e),s=typeof e=="object"&&e.definitions?Object.entries(e.definitions).reduce((p,[d,x])=>({...p,[d]:se(x._def,{...r,currentPath:[...r.basePath,r.definitionPath,d]},true)??Le(r)}),{}):void 0,n=typeof e=="string"?e:e?.nameStrategy==="title"?void 0:e?.name,o=se(t._def,n===void 0?r:{...r,currentPath:[...r.basePath,r.definitionPath,n]},false)??Le(r),i=typeof e=="object"&&e.name!==void 0&&e.nameStrategy==="title"?e.name:void 0;i!==void 0&&(o.title=i),r.flags.hasReferencedOpenAiAnyType&&(s||(s={}),s[r.openAiAnyTypeName]||(s[r.openAiAnyTypeName]={type:["string","number","integer","boolean","array","null"],items:{$ref:r.$refStrategy==="relative"?"1":[...r.basePath,r.definitionPath,r.openAiAnyTypeName].join("/")}}));let c=n===void 0?s?{...o,[r.definitionPath]:s}:o:{$ref:[...r.$refStrategy==="relative"?[]:r.basePath,r.definitionPath,n].join("/"),[r.definitionPath]:{...s,[n]:o}};return r.target==="jsonSchema7"?c.$schema="http://json-schema.org/draft-07/schema#":(r.target==="jsonSchema2019-09"||r.target==="openAi")&&(c.$schema="https://json-schema.org/draft/2019-09/schema#"),r.target==="openAi"&&("anyOf"in c||"oneOf"in c||"allOf"in c||"type"in c&&Array.isArray(c.type))&&console.warn("Warning: OpenAI may not support schemas with unions as roots! Try wrapping it in an object property."),c};var GN={_media:{create:chunkAK754S3T_cjs.d.MEDIA_UPLOAD,update:chunkAK754S3T_cjs.d.MEDIA_UPLOAD,delete:chunkAK754S3T_cjs.d.MEDIA_DELETE}};function la(t,e){let r=GN[t];return r?r[e]:`collection.${e}`}function zN(t){let e=t.headers.get("x-forwarded-for");return e?e.split(",")[0].trim():t.headers.get("x-real-ip")||"unknown"}function Nc(t,e,r,s,n){e?.apiKeyId&&t&&t.createAuditLog({action:"api_request",userId:e.userId||"",resource:"api_key",resourceId:e.apiKeyId,success:true,metadata:{endpoint:r,method:s,ip:zN(n)}});}function Mc(t){return t.baseUpdatedAt??t._baseUpdatedAt}function qd(t){let{baseUpdatedAt:e,_baseUpdatedAt:r,...s}=t;return s}function Fd(t,e){return {error:"Document has changed since you started editing",code:"REVISION_CONFLICT",conflict:{expectedUpdatedAt:t??null,actualUpdatedAt:e.updatedAt??null,current:e}}}async function Ie(t,e,r,s,n,o,i=true,c="none"){return await chunkAK754S3T_cjs.b(t,e,{user:s,req:r,tenantId:n,apiKey:o},{enablePublicAccess:i,defaultAccess:c})}async function tr(t,e,r,s,n,o=true){return await chunkAK754S3T_cjs.c(t,e,{user:s,req:r,tenantId:n},{enablePublicAccess:o})}async function W(t,e,r,s){if(r)return {user:r,tenantId:s,apiKeyContext:void 0,authType:"static"};if(e){let n=await e(t);if(n.status===200&&n.user)return {user:n.user,tenantId:n.tenantContext?.tenantId,apiKeyContext:n.apiKeyContext,authType:n.authType}}return {user:void 0,tenantId:void 0,apiKeyContext:void 0,authType:void 0}}async function KN(t,e){if("dialect"in t&&t.dialect==="postgres"&&t instanceof chunk6KUL2BSA_cjs.c)return new chunkB3GDQ7UI_cjs.a({db:t.client});if("dialect"in t&&t.dialect==="sqlite"&&t instanceof chunk6KUL2BSA_cjs.c)return new qa({db:t.client});if("dialect"in t&&t.dialect==="mongodb"){let s=t;return new chunk5DWYVUQR_cjs.a({db:()=>s.db})}let r=Ga.resolve(e,"data","auth.db");return new chunkBHR7OAU4_cjs.a({path:process.env.KYRO_AUTH_DB_PATH||r})}async function O_(t){let{registry:e,db:r,authSecret:s,authAdapter:n,checkSession:o,user:i,tenantId:c,cors:p,webhookService:d,settings:x}=t,w=new eu;function A(l){if(Array.isArray(l))return l.map(A);if(l!==null&&typeof l=="object"){let y={};for(let v in l)v!=="attrs"&&(y[v]=A(l[v]));return y}return l}w.use("*",async(l,y)=>{await y();let v=l.req.header("referer")||"";if(!(l.req.header("x-kyro-admin")==="true"||v.includes("/admin"))){let g=l.res.headers.get("Content-Type");if(g&&g.includes("application/json"))try{let _=await l.res.clone().json(),C=A(_);l.res=l.json(C,l.res.status);}catch{}}});for(let l of e.getPlugins())typeof l.serverMiddleware=="function"&&l.serverMiddleware(w);let L=x?.access?.apiAccess,O=x?.access?.enablePublicAccess??false,F=x?.access?.defaultCollectionAccess??"none";L?.requireAuth;let ee=process.cwd(),we=ee.endsWith("admin")?Ga.resolve(ee,".."):ee,V=n||await KN(r,we),H=Lm({db:r,userLookup:async l=>await V.findUserById(l)||null}),Lt=L?.cors?.allowedOrigins,gs=p?.origins,Lr=Array.isArray(Lt)?Lt:typeof Lt=="string"&&Lt?Lt.split(`
124
- `).map(l=>l.trim()).filter(Boolean):[],Fe=Lr.length>0?Lr:gs||[];(Fe.length>0||p)&&w.use("*",async(l,y)=>{let v=l.req.header("Origin")||"*";if(Fe.length>0&&!Fe.includes(v))return l.json({error:"Origin not allowed"},403);let R=Fe.length>0?v:"*";if(l.header("Access-Control-Allow-Origin",R),l.header("Access-Control-Allow-Methods","GET, POST, PATCH, DELETE, OPTIONS"),l.header("Access-Control-Allow-Headers","Content-Type, Authorization, X-API-Key"),p?.credentials&&l.header("Access-Control-Allow-Credentials","true"),l.req.method==="OPTIONS")return l.text("");await y();});let gr=x?.access?.rateLimiting,rr;if(gr?.enabled){let l=gr.maxRequests||100,y=gr.windowMs||6e4;rr=new Ma({"api:general":{window:y,max:l}}),w.use("/api/*",async(v,R)=>{if(!rr)return R();let g=v.req.header("CF-Connecting-IP")||v.req.header("X-Forwarded-For")?.split(",")[0]?.trim()||v.req.header("X-Real-IP")||"unknown",f=await rr.check("api:general",g);if(v.header("X-RateLimit-Limit",String(l)),v.header("X-RateLimit-Remaining",String(f.remaining)),v.header("X-RateLimit-Reset",String(f.resetAt)),!f.allowed)return v.json({error:"Too many requests",retryAfter:f.retryAfter},429);await R();});}let Re=new Ua({redis:V,jwtSecret:s||"change-me",baseUrl:process.env.KYRO_BASE_URL||"http://localhost:4321",rateLimiter:rr});chunkP7XYIKL6_cjs.k.fromConfig(r).then(l=>{l&&(Re.email=l);}).catch(l=>{console.error("[Email] Failed to initialize transport from config:",l);}),w.post("/api/auth/login",async l=>Re.login(l.req.raw)),w.post("/api/auth/register",async l=>{try{let y=await r.findOne({collection:"_globals_system",where:{}});if(y&&y.enableRegistration===!1)return l.json({error:"User registration is currently disabled by administrator."},403);if(y?.defaultRegistrationRole){let v=l.req.raw;if((v.headers.get("content-type")||"").includes("application/json")){let g=await l.req.json();g.role||(g.role=y.defaultRegistrationRole);let f=new Request(v.url,{method:v.method,headers:v.headers,body:JSON.stringify(g)});return Re.register(f)}}}catch{}return Re.register(l.req.raw)}),w.post("/api/auth/logout",async l=>Re.logout(l.req.raw)),w.post("/api/auth/refresh",async l=>Re.refresh(l.req.raw)),w.get("/api/auth/me",async l=>Re.me(l.req.raw)),w.post("/api/auth/forgot-password",async l=>Re.forgotPassword(l.req.raw)),w.post("/api/auth/reset-password",async l=>Re.resetPassword(l.req.raw)),w.post("/api/auth/change-password",async l=>Re.changePassword(l.req.raw)),w.get("/api/auth/verify-email",async l=>Re.verifyEmail(l.req.raw)),w.post("/api/auth/verify-email",async l=>Re.verifyEmail(l.req.raw)),w.get("/api/auth/verify",async l=>Re.verifyEmail(l.req.raw)),w.post("/api/auth/verify",async l=>Re.verifyEmail(l.req.raw)),w.get("/api/auth/sessions",async l=>Re.listSessions(l.req.raw)),w.post("/api/auth/sessions/refresh",async l=>Re.refreshSession(l.req.raw)),w.delete("/api/auth/sessions",async l=>Re.revokeOtherSessions(l.req.raw)),w.delete("/api/auth/sessions/:id",async l=>Re.revokeSession(l.req.raw,l.req.param("id"))),w.put("/api/auth/sessions/:id/name",async l=>Re.renameSession(l.req.raw,l.req.param("id"))),w.get("/api/auth/access",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Not authenticated"},401);let R={},g={};for(let f of e.getCollections()){let _={read:(await Ie(f,"read",l.req.raw,y,v,void 0,O,F)).allowed,create:(await Ie(f,"create",l.req.raw,y,v,void 0,O,F)).allowed,update:(await Ie(f,"update",l.req.raw,y,v,void 0,O,F)).allowed,delete:(await Ie(f,"delete",l.req.raw,y,v,void 0,O,F)).allowed};R[f.slug]=_;}for(let f of e.getGlobals()){let _={read:(await tr(f,"read",l.req.raw,y,v,O)).allowed,update:(await tr(f,"update",l.req.raw,y,v,O)).allowed};g[f.slug]=_;}return l.json({collections:R,globals:g})}catch(y){return l.json({error:y.message},500)}});let $t=typeof e.hasCollection=="function"&&e.hasCollection("users")?e.getCollection("users"):(()=>{try{return e.getCollection("users")}catch{return chunkZO3YB5DK_cjs.a}})();w.get("/api/users",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c),R=await Ie($t,"read",l.req.raw,y,v,void 0,O,F);if(!R.allowed)return l.json({error:R.error},R.status||403);let g=parseInt(l.req.query("page")||"1"),f=Math.min(parseInt(l.req.query("limit")||"10"),100),_=l.req.query("search")||void 0,C=[],S=0;if(typeof V.findUsers=="function"){let E=await V.findUsers({page:g,limit:f,search:_});C=E.users||[],S=E.total||0;}else {let E=await r.find({collection:"users",page:g,limit:f,where:_?{email:{contains:_}}:{},tenantId:v});C=E.docs||[],S=E.totalDocs||0;}return l.json({docs:C,totalDocs:S,limit:f,totalPages:Math.ceil(S/f)||1,page:g,pagingCounter:(g-1)*f+1,hasPrevPage:g>1,hasNextPage:g<Math.ceil(S/f),prevPage:g>1?g-1:null,nextPage:g<Math.ceil(S/f)?g+1:null})}catch(y){return console.error("[API] Error listing users:",y),l.json({error:y.message},500)}}),w.get("/api/users/:id",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c),R=l.req.param("id"),g=await V.findUserById(R);return g?l.json({data:g}):l.json({error:"User not found"},404)}catch(y){return l.json({error:y.message},500)}}),w.post("/api/users",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c),R=await Ie($t,"create",l.req.raw,y,v,void 0,O,F);if(!R.allowed)return l.json({error:R.error},R.status||403);let g=await l.req.json();if(!g.email||!g.password)return l.json({error:"Email and password are required"},400);if(await V.findUserByEmail(g.email))return l.json({error:"Email already in use"},400);let _=g.role||"customer";if(_!=="customer"&&y?.role!=="super_admin")return l.json({error:"Forbidden: Only super_admin can assign administrative roles"},403);let C=await V.createUser({email:g.email,password:g.password,name:g.name,role:_,avatar:g.avatar,tenantId:g.tenantId});return y&&V?.createAuditLog({action:"user_create",userId:y.id,resource:"users",resourceId:C.id,success:!0}),l.json({data:C,message:"User created successfully"},201)}catch(y){return l.json({error:y.message},500)}}),w.patch("/api/users/:id",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c),R=await Ie($t,"update",l.req.raw,y,v,void 0,O,F);if(!R.allowed)return l.json({error:R.error},R.status||403);let g=l.req.param("id"),f=await l.req.json(),_=await V.findUserById(g);if(!_)return l.json({error:"User not found"},404);let C={};if(f.name!==void 0&&(C.name=f.name),f.email!==void 0&&(C.email=f.email),f.role!==void 0&&f.role!==_.role){if(y?.role!=="super_admin")return l.json({error:"Forbidden: Only super_admin can modify user roles"},403);C.role=f.role;}f.avatar!==void 0&&(C.avatar=typeof f.avatar=="object"&&f.avatar!==null?f.avatar.id||String(f.avatar):f.avatar),f.tenantId!==void 0&&(C.tenantId=f.tenantId),f.emailVerified!==void 0&&(C.emailVerified=f.emailVerified),f.locked!==void 0&&(C.locked=f.locked),f.failedLoginAttempts!==void 0&&(C.failedLoginAttempts=f.failedLoginAttempts),f.lastLogin!==void 0&&(C.lastLogin=f.lastLogin);let S=await V.updateUser(g,C);return S?(y&&(V?.createAuditLog({action:"user_update",userId:y.id,resource:"users",resourceId:g,success:!0}),f.role&&_.role!==f.role&&V?.createAuditLog({action:"role_change",userId:y.id,resource:"users",resourceId:g,success:!0,metadata:{oldRole:_.role,newRole:f.role}})),l.json({data:S,message:"User updated successfully"})):l.json({error:"User update failed"},500)}catch(y){return l.json({error:y.message},500)}}),w.delete("/api/users/:id",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c),R=await Ie($t,"delete",l.req.raw,y,v,void 0,O,F);if(!R.allowed)return l.json({error:R.error},R.status||403);let g=l.req.param("id");if(y&&y.id===g)return l.json({error:"You cannot delete your own account"},403);let f=await V.findUserById(g);return f?await V.deleteUser(g)?(y&&V?.createAuditLog({action:"user_delete",userId:y.id,resource:"users",resourceId:g,success:!0}),l.json({data:f,message:"User deleted successfully"})):l.json({error:"User deletion failed"},500):l.json({error:"User not found"},404)}catch(y){return l.json({error:y.message},500)}}),w.get("/api/auth/audit-logs",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c),R=e.getCollection("audit_logs");if(R){let D=await Ie(R,"read",l.req.raw,y,v,void 0,O,F);if(!D.allowed)return l.json({error:D.error},D.status||403)}else if(!y)return l.json({error:"Authentication required"},401);let g=parseInt(l.req.query("page")||"1"),f=Math.min(parseInt(l.req.query("limit")||"50"),100),_=l.req.query("action")||void 0,C=l.req.query("userId")||void 0,S=l.req.query("resource")||void 0,E=await V.findAuditLogs({action:_,userId:C,resource:S,limit:f,offset:(g-1)*f});return l.json({docs:E.logs,totalDocs:E.total,limit:f,totalPages:Math.ceil(E.total/f),page:g,pagingCounter:(g-1)*f+1,hasPrevPage:g>1,hasNextPage:g<Math.ceil(E.total/f),prevPage:g>1?g-1:null,nextPage:g<Math.ceil(E.total/f)?g+1:null})}catch(y){return console.error("[API] Error listing audit logs:",y),l.json({error:y.message},500)}});let Bt=null,$r=null,ht=async()=>{if($r)throw $r;if(!Bt)try{let l="sqlite";"dialect"in r&&r.dialect==="postgres"&&r instanceof chunk6KUL2BSA_cjs.c?l=r.dialect:"dialect"in r&&r.dialect==="mongodb"&&(l="mongodb");let y=l==="postgres"&&r instanceof chunk6KUL2BSA_cjs.c?r.client:r;Bt=await Tc.init(y,{dialect:l});}catch(l){throw console.error("[getMedia] Init error:",l),$r=l,l}return Bt};w.get("/api/media",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht(),R=new URL(l.req.url).origin,g=parseInt(l.req.query("page")||"1"),f=parseInt(l.req.query("limit")||"30"),_=l.req.query("search")||"",C=l.req.query("type")||"",S=l.req.query("folder")||"",E=await v.find({page:g,limit:f,search:_,type:C,folder:S},R);return l.json(E)}catch(y){return console.error("[Media] find error:",y),l.json({error:y.message},500)}}),w.post("/api/media/upload",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht(),R=l.req.header("content-type")||"",g=new URL(l.req.url).origin;if(R.includes("multipart/form-data")){let E=await l.req.formData(),D=E.get("file"),P=E.get("folder")||"";if(!D)return l.json({error:"No file uploaded"},400);let j=await v.upload(D,P,g);return l.json(j)}let f=await l.req.json(),{url:_}=f,C=f.folder||"";if(!_)return l.json({error:"No URL provided"},400);let S=await v.uploadFromUrl(_,C,g);return l.json(S)}catch(y){return console.error("[Media] upload error:",y),l.json({error:y.message},500)}}),w.get("/api/media/folders",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let R=await(await ht()).listFolders();return l.json(R)}catch(y){return console.error("[Media] folders error:",y),l.json({error:y.message},500)}}),w.post("/api/media/folders",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht(),R=await l.req.json(),{name:g,parentPath:f}=R;return g?(await v.createFolder(g,f||""),l.json({message:"Folder created",path:f?`${f}/${g}`:g})):l.json({error:"Folder name is required"},400)}catch(y){return console.error("[Media] create folder error:",y),l.json({error:y.message},500)}}),w.delete("/api/media/folders",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht(),R=l.req.query("path");return R?(await v.deleteFolder(R),l.json({message:"Folder deleted"})):l.json({error:"Path is required"},400)}catch(y){return console.error("[Media] delete folder error:",y),l.json({error:y.message},500)}}),w.delete("/api/media/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht(),R=l.req.param("id"),g=new URL(l.req.url).origin;return await v.delete(R,g),l.json({success:!0})}catch(y){return console.error("[Media] delete error:",y),l.json({error:y.message},500)}}),w.get("/api/media/file/:key{.+$}",async l=>{let y=l.req.param("key"),v=globalThis.STORAGE_BUCKET;if(v){let R=await v.get(y);if(!R)return l.notFound();let g=new Headers;return R.writeHttpMetadata(g),g.set("etag",R.httpEtag),new Response(R.body,{headers:g})}return l.notFound()}),w.get("/api/media/resize",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=l.req.query("url"),R=parseInt(l.req.query("w")||"0"),g=parseInt(l.req.query("h")||"0"),f=l.req.query("fit")||"cover",_=parseFloat(l.req.query("cx")||"0"),C=parseFloat(l.req.query("cy")||"0"),S=parseFloat(l.req.query("cw")||"0"),E=parseFloat(l.req.query("ch")||"0");if(!v)return l.json({error:"URL is required"},400);let P=(await ht()).storage;if(P.name!=="local")return l.redirect(v);let j=P.config?.uploadDir||Ga.join(process.cwd(),"public","uploads"),N=P.config?.baseUrl||"/uploads";if(!v.startsWith(N))return l.redirect(v);let z=v.replace(N,""),Y=Ga.join(j,z);if(!fs$1.existsSync(Y))return l.json({error:"File not found"},404);let ue=fs$1.readFileSync(Y),{default:J}=await import('sharp'),ye=J(ue);if(S>0&&E>0){let Xe=await J(ue).metadata(),Xr=Xe.width||0,St=Xe.height||0;if(Xr>0&&St>0){let It=Math.max(0,Math.min(Math.round(_/100*Xr),Xr-1)),js=Math.max(0,Math.min(Math.round(C/100*St),St-1)),I_=Math.max(1,Math.min(Math.round(S/100*Xr),Xr-It)),D_=Math.max(1,Math.min(Math.round(E/100*St),St-js));ye=ye.extract({left:It,top:js,width:I_,height:D_});}}(R>0||g>0)&&(ye=ye.resize({width:R>0?R:void 0,height:g>0?g:void 0,fit:f}));let Je=await ye.toBuffer(),Nt=await J(ue).metadata();return l.header("Content-Type",`image/${Nt.format||"webp"}`),l.header("Cache-Control","public, max-age=31536000, immutable"),l.body(Je)}catch(y){return console.error("[Media] resize error:",y),l.json({error:y.message},500)}}),w.get("/api/media/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht(),R=l.req.param("id"),g=new URL(l.req.url).origin,f=await v.findById(R,g);return f?l.json(f):l.json({error:"Media not found"},404)}catch(y){return console.error("[Media] get error:",y),l.json({error:y.message},500)}}),w.patch("/api/media/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht(),R=l.req.param("id"),g=await l.req.json(),f=new URL(l.req.url).origin,_=["folder","metadata","title","alt","caption","originalName"],C={};for(let S of _)g[S]!==void 0&&(C[S]=g[S]);if(Object.keys(C).length>0){let S=await v.update(R,C,f);return l.json({doc:S})}return l.json({error:"No valid fields to update"},400)}catch(y){return console.error("[Media] update error:",y),l.json({error:y.message},500)}}),w.get("/api/media/test",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht();return l.json({status:v?"initialized":"failed",serviceType:v?.constructor?.name})}catch(y){return console.error("[test] Error:",y),l.json({error:y.message,type:y.constructor?.name,stack:y.stack},500)}}),w.get("/api/storage-status",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=typeof globalThis.STORAGE_BUCKET<"u"||typeof l.env?.STORAGE_BUCKET<"u",R=v,g=v?"cloudflare_r2":"local";if(r)try{let f=r.prepare('SELECT provider FROM "_globals_storage-settings" LIMIT 1').get();f&&f.provider&&(R=!0,g=f.provider==="aws"?"s3":f.provider);}catch{try{let f=await r.findOne({collection:"_globals_storage-settings",where:{},draft:!0});f&&f.provider&&(R=!0,g=f.provider==="aws"?"s3":f.provider);}catch{}}return l.json({provider:g,configured:R,usage:0,limit:"unlimited"})}catch(y){return console.error("[Storage] status error:",y),l.json({error:y.message},500)}}),w.get("/api/plugins",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=e.getPlugins(),R=e.storageProviders,g=await Promise.all(v.map(async f=>{let _=!0,C=f.name,S={};try{let P=await r.findOne({collection:"_globals_plugin-settings",where:{},draft:!0});P&&P.states&&(S=P.states);}catch{}S[C]!==void 0&&(_=S[C]),R.setPluginEnabled(C,_);let E=C.replace(/^@[^/]+\//,"");E=E.replace(/^(plugin|kyro)-/,"");let D={ai:"AI",seo:"SEO",s3:"S3",aws:"AWS",api:"API",ui:"UI",ftp:"FTP"};if(E=E.split("-").map(P=>{let j=P.toLowerCase();return D[j]?D[j]:P.charAt(0).toUpperCase()+P.slice(1)}).join(" "),E.toLowerCase().startsWith("storage ")){let P=E.split(" ");P.length===2&&(E=`${P[1]} Storage`);}return {id:C,name:f.displayName||E,version:f.version||"1.0.0",description:f.description||"",enabled:_,status:_?"active":"disabled"}}));return l.json(g)}catch(y){return console.error("[Plugins] list error:",y),l.json({error:y.message},500)}}),w.put("/api/plugins/:name/toggle",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=l.req.param("name"),R=e.storageProviders,f=!R.isPluginEnabled(v),_=[];if(!f)for(let S of R.getAll())S.pluginName===v&&_.push(S.type);if(!(l.req.query("force")==="1")&&!f&&_.length>0){let S="local";try{let E=r?.prepare?.('SELECT provider FROM "_globals_storage-settings" LIMIT 1')?.get();E?.provider&&(S=E.provider);}catch{try{let E=await r?.findOne?.({collection:"_globals_storage-settings",where:{},draft:!0});E?.provider&&(S=E.provider);}catch{}}if(_.includes(S))return l.json({error:`Cannot disable "${v}" \u2014 storage provider "${S}" is currently active. Switch to Local storage first.`,requiresAction:!0,activeProvider:S},409)}try{let S={},E="global",D=await r.findOne({collection:"_globals_plugin-settings",where:{},draft:!0});D&&(S=D.states||{},E=D.id),S[v]=f,D?await r.update({collection:"_globals_plugin-settings",id:E,data:{states:S}}):await r.create({collection:"_globals_plugin-settings",data:{states:S,id:"global"}});}catch(S){console.warn(`[Plugins] Could not persist state for "${v}":`,S);}return R.setPluginEnabled(v,f),l.json({name:v,enabled:f})}catch(y){return console.error("[Plugins] toggle error:",y),l.json({error:y.message},500)}}),w.get("/api/health",l=>l.json({status:"ok",version:"0.12.46",collections:e.getCollectionSlugs(),timestamp:new Date().toISOString()})),w.get("/api/metrics",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let R=y.role==="admin"||y.role==="super_admin",f=e.getCollectionSlugs().filter(N=>!["users","audit_logs","media","_globals_access-settings","_globals_brand-settings"].includes(N)&&!N.startsWith("_globals_")).filter(N=>R||chunk7WMMKGEO_cjs.a(y,`${N}:read`)),_=0,C={};await Promise.all(f.map(async N=>{try{let Y=(await r.find({collection:N,where:{},limit:1,page:1,tenantId:v})).totalDocs??0;_+=Y,C[N]=Y;}catch{}}));let S=0;try{S=(await r.find({collection:"media",where:{},limit:1,page:1,tenantId:v})).totalDocs??0;}catch{}let E=0;try{E=(await r.find({collection:"users",where:{},limit:1,page:1,tenantId:v})).totalDocs??0;}catch{}let D=0;try{if(d){let N=await d.getWebhooks();D=Array.isArray(N)?N.length:0;}}catch{}let P=0;try{P=(await r.find({collection:chunkDUO523BH_cjs.d,where:{},limit:1,page:1,tenantId:v})).totalDocs??0;}catch{}let j=_+S+E;return l.json({totalDocuments:_,totalMedia:R||chunk7WMMKGEO_cjs.a(y,"media:read")?S:void 0,totalUsers:R||chunk7WMMKGEO_cjs.a(y,"users:read")?E:void 0,totalWebhooks:R?D:void 0,totalApiKeys:R?P:void 0,totalStoredRecords:j,collectionCounts:C,collections:f.length,timestamp:new Date().toISOString()})}catch(y){return console.error("[API] Metrics error:",y),l.json({error:y.message},500)}}),w.get("/api/analytics",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);if(!(y.role==="admin"||y.role==="super_admin"))return l.json({error:"Unauthorized"},403);let f=(await r.find({collection:"orders",where:{},limit:1e3,page:1,tenantId:v})).docs||[],_=await r.findOne({collection:"_globals_store-settings",where:{},tenantId:v}),C=_?.currency?.code||_?.currency||"USD",S={},E={},D={};f.forEach(N=>{let z=N.createdAt||N.updatedAt,Y=z?new Date(z).toISOString().split("T")[0]:new Date().toISOString().split("T")[0];S[Y]||(S[Y]=0),E[Y]||(E[Y]=0);let ue=typeof N.total=="number"?N.total:parseFloat(String(N.total||0));S[Y]+=isNaN(ue)?0:ue,E[Y]+=1;let J=N.orderStatus||N.status||"pending";D[J]=(D[J]||0)+1;});let P=Object.keys(S).sort().map(N=>({date:N,revenue:Math.round(S[N]*100)/100,orders:E[N]})),j=Math.round(P.reduce((N,z)=>N+z.revenue,0)*100)/100;return l.json({chartData:P,totalRevenue:j,totalOrders:f.length,ordersByStatus:D,currencyCode:typeof C=="string"?C:"USD"})}catch(y){return l.json({error:y.message},500)}}),w.get("/api/kyro/schema",async l=>{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=g=>g.map(f=>{let _={name:f.name,type:f.type,label:f.label,required:f.required??false,unique:f.unique??false,indexed:f.indexed??false,defaultValue:f.defaultValue,admin:f.admin?{...f.admin}:void 0};return f.minLength!==void 0&&(_.minLength=f.minLength),f.maxLength!==void 0&&(_.maxLength=f.maxLength),f.pattern!==void 0&&(_.pattern=f.pattern),f.variant!==void 0&&(_.variant=f.variant),f.hasMany!==void 0&&(_.hasMany=f.hasMany),f.min!==void 0&&(_.min=f.min),f.max!==void 0&&(_.max=f.max),f.step!==void 0&&(_.step=f.step),f.integer!==void 0&&(_.integer=f.integer),f.options&&(_.options=f.options),f.relationTo&&(_.relationTo=f.relationTo),f.maxDepth!==void 0&&(_.maxDepth=f.maxDepth),f.minRows!==void 0&&(_.minRows=f.minRows),f.maxRows!==void 0&&(_.maxRows=f.maxRows),f.localized!==void 0&&(_.localized=f.localized),f.language&&(_.language=f.language),f.format&&(_.format=f.format),f.allowedTypes&&(_.allowedTypes=f.allowedTypes),f.maxSize&&(_.maxSize=f.maxSize),(f.type==="group"||f.type==="row"||f.type==="collapsible"&&f.fields)&&(_.fields=v(f.fields)),f.type==="array"&&f.fields&&(_.fields=v(f.fields)),f.type==="blocks"&&f.blocks&&(_.blocks=f.blocks.map(C=>({slug:C.slug,label:C.label,fields:v(C.fields)}))),f.type==="tabs"&&f.tabs&&(_.tabs=f.tabs.map(C=>({label:C.label,name:C.name,fields:v(C.fields)}))),_}),R={collections:{},globals:{}};for(let g of e.getCollections()){let f=g.slug;try{R.collections[f]={slug:f,label:g.label||f,fields:v(g.fields),jsonSchema:to(e.getZodSchema(f),{target:"openApi3"}),createSchema:to(e.getCreateZodSchema(f),{target:"openApi3"}),updateSchema:to(e.getUpdateZodSchema(f),{target:"openApi3"}),procedures:{find:{collection:f,where:"Record<string,any>",sort:"string",limit:"number",page:"number",depth:"number",select:"string[]",draft:"boolean"},findByID:{collection:f,id:"string",depth:"number",select:"string[]",draft:"boolean"},create:{collection:f,data:"Record<string,any>",depth:"number",select:"string[]"},update:{collection:f,id:"string",data:"Record<string,any>",depth:"number",select:"string[]",baseUpdatedAt:"string"},delete:{collection:f,id:"string"},count:{collection:f,where:"Record<string,any>"}}};}catch{}}for(let g of e.getGlobals()){let f=g.slug,_=g.fields;if(f==="storage-settings"){let C=e.storageProviders,S=C.getAll(),E=new Set(C.getAllAvailable(P=>C.isPluginEnabled(P)).map(P=>P.type));E.add("local");let D=new Set(S.map(P=>P.type));_=_.filter(P=>P.type==="group"&&P.name&&D.has(P.name)?E.has(P.name):true).map(P=>P.name==="provider"&&P.type==="select"?{...P,options:P.options.filter(j=>E.has(j.value))}:P);}try{R.globals[f]={slug:f,label:g.label||f,fields:v(_),jsonSchema:to(e.getZodSchema(f),{target:"openApi3"}),procedures:{get:{},update:{data:"Record<string,any>"}}};}catch{}}return l.json(R)}),w.get("/api/collections",async l=>{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=e.getCollections().map(R=>({slug:R.slug,label:R.label||R.slug,fields:R.fields.filter(g=>g.name).map(g=>({name:g.name,type:g.type,required:g.required,label:g.label}))}));return l.json(v)});function ro(l,y,v){if(v in y)return y[v];for(let R of l)if(R.name){if(R.type==="tabs"&&R.tabs){let g=y[R.name];if(g&&typeof g=="object"&&v in g)return g[v]}if((R.type==="group"||R.type==="collapsible")&&R.fields){let g=y[R.name];if(g&&typeof g=="object"){if(v in g)return g[v];let f=ro(R.fields,g,v);if(f!==void 0)return f}}}}w.get("/api/search",async l=>{try{let y=l.req.query("q")||"",v=l.req.query("collections")||"",R=Math.min(parseInt(l.req.query("limit")||"10"),50);if(!y||y.length<2)return l.json({results:[],message:"Query too short"});let{user:g,tenantId:f}=await W(l.req.raw,H,i,c),_=v?v.split(",").filter(Boolean):e.getCollectionSlugs(),C=[],S=new RegExp(y.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"i");for(let E of e.getCollections()){if(!_.includes(E.slug)||!(await Ie(E,"read",l.req.raw,g,f,void 0,O,F)).allowed)continue;let P=E.fields.filter(j=>j.name&&j.name!=="id"&&(j.type==="text"||j.type==="email"||j.type==="textarea"||j.type==="richtext"||j.indexed)&&!j.admin?.hidden).map(j=>j.name);if(P.length!==0)try{let j=P.map(z=>{let Y={};return Y[z]={like:`%${y}%`},Y}),N=await r.find({collection:E.slug,where:{OR:j},limit:R,tenantId:f});await chunkAK754S3T_cjs.a(N.docs,E.fields,r,e,1,0);for(let z of N.docs){let Y=E.admin?.useAsTitle||P.find(J=>J==="title"||J==="name"||J==="heading"||J==="slug"),ue=Y?ro(E.fields,z,Y)??z.id:z.id;C.push({collection:E.slug,label:E.label||E.slug,id:z.id,title:String(ue||"Untitled"),doc:z});}}catch(j){console.error(`Search error for ${E.slug}:`,j);}}return C.sort((E,D)=>E.label.localeCompare(D.label)),l.json({results:C})}catch(y){return l.json({error:y.message,results:[]},500)}}),w.get("/api/keys",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:read"))return l.json({error:"Forbidden"},403);let R=parseInt(l.req.query("page")||"1"),g=Math.min(parseInt(l.req.query("limit")||"50"),100),f=await r.find({collection:chunkDUO523BH_cjs.d,where:{},page:R,limit:g,tenantId:v}),_=(f.docs||[]).map(C=>({id:C.id,name:C.name,keyPrefix:C.keyPrefix,permissions:C.permissions||[],lastUsed:C.lastUsedAt,createdAt:C.createdAt}));return l.json({docs:_,totalDocs:f.totalDocs||_.length,totalPages:f.totalPages||1})}catch(y){return console.error("[ApiKeys] GET error:",y),l.json({error:y.message},500)}}),w.post("/api/keys",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);let v=await l.req.json();if(!v.name||typeof v.name!="string")return l.json({error:"name is required"},400);let R=chunkDUO523BH_cjs.i(),g=await r.create({collection:chunkDUO523BH_cjs.d,data:{userId:y.id,name:v.name,key:R,keyPrefix:chunkDUO523BH_cjs.j(R),permissions:Array.isArray(v.permissions)?v.permissions:["*"],expiresAt:v.expiresAt||null,createdAt:new Date().toISOString()}});return await V?.createAuditLog({action:"api_key_create",userId:y.id,resource:"api_key",resourceId:g.id,success:!0,metadata:{keyName:v.name}}),l.json({...g,key:R,permissions:Array.isArray(v.permissions)?v.permissions:["*"]},201)}catch(y){return console.error("[ApiKeys] POST error:",y),l.json({error:y.message},500)}}),w.delete("/api/keys/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);let v=l.req.param("id"),R=await r.findByID({collection:chunkDUO523BH_cjs.d,id:v});return R?(await r.delete({collection:chunkDUO523BH_cjs.d,id:v}),await V?.createAuditLog({action:"api_key_delete",userId:y.id,resource:"api_key",resourceId:v,success:!0,metadata:{keyName:R.name}}),l.json({message:"API key deleted"})):l.json({error:"API key not found"},404)}catch(y){return console.error("[ApiKeys] DELETE error:",y),l.json({error:y.message},500)}}),w.patch("/api/keys/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);let v=l.req.param("id"),R=await l.req.json(),g=await r.findByID({collection:chunkDUO523BH_cjs.d,id:v});if(!g)return l.json({error:"API key not found"},404);let f={};if(typeof R.name=="string"&&R.name.trim()&&(f.name=R.name.trim()),Array.isArray(R.permissions)&&(f.permissions=R.permissions),R.expiresAt!==void 0&&(f.expiresAt=R.expiresAt||null),Object.keys(f).length===0)return l.json({error:"Nothing to update"},400);let _=await r.update({collection:chunkDUO523BH_cjs.d,id:v,data:f});return l.json({..._,keyPrefix:g.keyPrefix})}catch(y){return console.error("[ApiKeys] PATCH error:",y),l.json({error:y.message},500)}}),w.post("/api/keys/:id/rotate",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);let v=l.req.param("id"),R=await r.findByID({collection:chunkDUO523BH_cjs.d,id:v});if(!R)return l.json({error:"API key not found"},404);let g=chunkDUO523BH_cjs.i(),f=await r.update({collection:chunkDUO523BH_cjs.d,id:v,data:{key:g,keyPrefix:chunkDUO523BH_cjs.j(g),lastUsedAt:null}});return await V?.createAuditLog({action:"api_key_rotate",userId:y.id,resource:"api_key",resourceId:v,success:!0,metadata:{keyName:R.name}}),l.json({...f,key:g,permissions:R.permissions,expiresAt:R.expiresAt})}catch(y){return console.error("[ApiKeys] rotate error:",y),l.json({error:y.message},500)}}),w.get("/api/webhooks/actions",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:read"))return l.json({error:"Forbidden"},403);let v={generic:{label:"Custom URL",description:"POST to any endpoint with Kyro payload",configFields:[],envVars:[]},"github-push":{label:"GitHub Push",description:"Push an empty commit to simulate a push event",configFields:[{name:"githubOwner",label:"Owner",required:!0,placeholder:"e.g., kyro-dev"},{name:"githubRepo",label:"Repository",required:!0,placeholder:"e.g., my-website"},{name:"githubBranch",label:"Branch",required:!1,placeholder:"main"}],envVars:["GITHUB_TOKEN"]}};return l.json({actions:v})}catch(y){return console.error("[Webhooks] actions error:",y),l.json({error:y.message},500)}}),w.get("/api/webhooks",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:read"))return l.json({error:"Forbidden"},403);if(!d)return l.json({error:"Webhook service not available"},503);let v=await d.getWebhooks();return l.json({docs:v})}catch(y){return console.error("[Webhooks] GET error:",y),l.json({error:y.message},500)}}),w.post("/api/webhooks",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);if(!d)return l.json({error:"Webhook service not available"},503);let v=await l.req.json(),R=await d.createWebhook(v);return await V?.createAuditLog({action:"webhook_create",userId:y.id,resource:"webhook",resourceId:R.id,success:!0,metadata:{name:R.name,url:R.url}}),l.json(R,201)}catch(y){return console.error("[Webhooks] POST error:",y),l.json({error:y.message},500)}}),w.get("/api/webhooks/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:read"))return l.json({error:"Forbidden"},403);if(!d)return l.json({error:"Webhook service not available"},503);let v=l.req.param("id"),R=await d.getWebhookById(v);return R?l.json(R):l.json({error:"Webhook not found"},404)}catch(y){return console.error("[Webhooks] GET :id error:",y),l.json({error:y.message},500)}}),w.patch("/api/webhooks/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);if(!d)return l.json({error:"Webhook service not available"},503);let v=l.req.param("id"),R=await l.req.json(),g=await d.updateWebhook(v,R);return g?(await V?.createAuditLog({action:"webhook_update",userId:y.id,resource:"webhook",resourceId:v,success:!0,metadata:{name:g.name}}),l.json(g)):l.json({error:"Webhook not found"},404)}catch(y){return console.error("[Webhooks] PATCH error:",y),l.json({error:y.message},500)}}),w.delete("/api/webhooks/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);if(!d)return l.json({error:"Webhook service not available"},503);let v=l.req.param("id"),R=await d.getWebhookById(v);return R?(await d.deleteWebhook(v),await V?.createAuditLog({action:"webhook_delete",userId:y.id,resource:"webhook",resourceId:v,success:!0,metadata:{name:R.name}}),l.json({message:"Webhook deleted"})):l.json({error:"Webhook not found"},404)}catch(y){return console.error("[Webhooks] DELETE error:",y),l.json({error:y.message},500)}}),w.post("/api/webhooks/:id/test",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);if(!d)return l.json({error:"Webhook service not available"},503);let v=l.req.param("id"),R=await d.testWebhook(v);return R?l.json(R):l.json({error:"Webhook not found"},404)}catch(y){return console.error("[Webhooks] test error:",y),l.json({error:y.message},500)}}),w.get("/api/webhooks/:id/history",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:read"))return l.json({error:"Forbidden"},403);if(!d)return l.json({error:"Webhook service not available"},503);let v=l.req.param("id"),R=Math.min(parseInt(l.req.query("limit")||"50"),100),g=await d.getDeliveryHistory(v,R);return l.json({docs:g})}catch(y){return console.error("[Webhooks] history error:",y),l.json({error:y.message},500)}});function so(l){let y={},v=["name","type","required","hasMany","relationTo","options","min","max","minLength","maxLength","defaultValue","label","localized","admin","unique","index","hidden","readOnly","deprecated"];for(let R of v)R in l&&(y[R]=l[R]);return l.fields&&(y.fields=l.fields.map(so)),l.tabs&&(y.tabs=l.tabs.map(R=>({label:R.label,name:R.name,fields:R.fields.map(so)}))),y}w.get("/api/__schema",async l=>{try{let{user:y,apiKeyContext:v}=await W(l.req.raw,H,i,c);if(!y&&!v)return l.json({error:"Unauthorized"},401);let g=e.getCollections().filter(f=>f.slug!=="users"&&f.slug!=="audit_logs").map(f=>({slug:f.slug,label:f.label,labelPlural:f.labelPlural,singularLabel:f.singularLabel,timestamps:f.timestamps,auth:!!f.auth,tenantScoped:!!f.tenantScoped,upload:f.upload?{staticDir:f.upload.staticDir,imageSizes:f.upload.imageSizes,mimeTypes:f.upload.mimeTypes}:void 0,fields:f.fields.map(so)}));return l.json(g)}catch(y){return console.error("[Schema] error:",y),l.json({error:y.message},500)}});let Hd=e.getCollections();for(let l of Hd){let R=function(g,f){let _=[],C=new Set([...Object.keys(g),...Object.keys(f)]);for(let S of C)S==="id"||S==="createdAt"||S==="updatedAt"||JSON.stringify(g[S])!==JSON.stringify(f[S])&&_.push({field:S,oldValue:S in g?g[S]:void 0,newValue:S in f?f[S]:void 0});return _};let y=l.slug;if(y==="users"||y==="audit_logs")continue;let v=`/api/${y}`;w.post(`${v}/dynamic-options/:fieldName`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"read",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=g.req.param("fieldName"),D=await g.req.json(),{data:P,siblingData:j}=D,N=vs(l.fields,E);if(!N)return g.json({error:"Field not found"},404);if(N.type!=="select")return g.json({error:"Field is not a select field"},400);let z=[];return typeof N.options=="function"?z=await N.options({data:P||{},siblingData:j||{}}):Array.isArray(N.options)&&(z=N.options),g.json({options:z})}catch(f){return g.json({error:f.message},500)}}),w.get(v,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"read",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);_&&r.setTenantContext({tenantId:_,userId:f?.id??"",role:f?.role,isSuperAdmin:f?.role==="super_admin"});let E=new URL(g.req.url),D=parseInt(E.searchParams.get("page")||"1"),P=Math.min(parseInt(E.searchParams.get("limit")||"10"),100),j=E.searchParams.get("sort")||void 0,N=parseInt(E.searchParams.get("depth")||"0"),z=E.searchParams.get("select")?.split(",")||void 0,Y=E.searchParams.get("draft"),ue=Y==="true"?!0:Y==="false"?!1:!!f,J={},ye=E.searchParams.get("where");if(ye)try{J=JSON.parse(ye);}catch{return g.json({error:"Invalid JSON in where parameter"},400)}let Je=await r.find({collection:y,where:J,sort:j,limit:P,page:D,depth:N,tenantId:_,select:z,draft:ue});return await chunkAK754S3T_cjs.a(Je.docs,l.fields,r,e,1,N),g.json(chunkZOVH6QT5_cjs.a(Je))}catch(f){return console.error("[API] list error:",f),g.json({error:f.message},500)}}),w.get(`${v}/:id/versions`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"read",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=g.req.param("id");if(!E)return g.json({error:"Missing document ID"},400);let D=new URL(g.req.url),P=D.searchParams.get("compareA"),j=D.searchParams.get("compareB");if(Nc(V,C,`${v}/${E}/versions`,"GET",g.req.raw),P&&j){let[ue,J]=await Promise.all([r.findVersionByID({collection:y,versionId:P,tenantId:_}),r.findVersionByID({collection:y,versionId:j,tenantId:_})]);if(!ue||!J)return g.json({error:"Version not found"},404);let ye=R(ue.data,J.data);return g.json({diffs:ye})}let N=parseInt(D.searchParams.get("page")||"1"),z=Math.min(parseInt(D.searchParams.get("limit")||"10"),100),Y=await r.findVersions({collection:y,documentId:E,page:N,limit:z,tenantId:_});return g.json(Y)}catch(f){return console.error("[API] versions error:",f),g.json({error:f.message},500)}}),w.put(`${v}/:id/draft`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"update",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=g.req.param("id"),D=await g.req.json(),P=Mc(D),j=await r.findByID({collection:y,id:E,tenantId:_,draft:!0});if(!j)return g.json({error:"Document not found"},404);let N;D.delta?N={...j,...D.delta}:N=D.data??qd(D);let z=await r.updateLatestVersion({collection:y,documentId:E,data:N,status:"draft",tenantId:_});return f&&V?.createAuditLog({action:"document_update",userId:f.id,resource:y,resourceId:E,success:!0,metadata:{type:"draft_save"}}),g.json({data:z,message:"Draft saved successfully"})}catch(f){return g.json({error:f.message},500)}}),w.delete(`${v}/:id/draft`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"update",g.req.raw,f,_,C,O,F);return S.allowed?(f&&V?.createAuditLog({action:"document_update",userId:f.id,resource:y,resourceId:g.req.param("id"),success:!0,metadata:{type:"draft_discard"}}),g.json({message:"Draft discarded successfully"})):g.json({error:S.error},S.status||403)}catch(f){return g.json({error:f.message},500)}}),w.get(`${v}/:id`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=new URL(g.req.url),E=S.searchParams.get("draft"),D=S.searchParams.get("kyroToken"),P=!1;if(E==="true"&&D&&s)try{let J=await Pa(D,s,"HS256");J&&J.type==="preview"&&J.collection===l.slug&&(P=!0);}catch(J){console.warn("Invalid preview token",J);}if(!P){let J=await Ie(l,"read",g.req.raw,f,_,C,O,F);if(!J.allowed)return g.json({error:J.error},J.status||403)}let j=g.req.param("id"),N=parseInt(S.searchParams.get("depth")||"0"),z=S.searchParams.get("select")?.split(",")||void 0,Y=E==="true"?!0:E==="false"?!1:!!f,ue=await r.findByID({collection:y,id:j,depth:N,tenantId:_,select:z,draft:Y});return !ue&&l.fields.some(J=>J.name==="slug")&&(ue=await r.findOne({collection:y,where:{slug:j},tenantId:_,draft:Y})),ue?(await chunkAK754S3T_cjs.a([ue],l.fields,r,e,1,N),g.json({data:chunkZOVH6QT5_cjs.a(ue)})):g.json({error:"Document not found"},404)}catch(f){return g.json({error:f.message},500)}}),w.post(`${v}/preview-url`,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await Ie(l,"read",g.req.raw,f,_);if(!C.allowed)return g.json({error:C.error||"Forbidden"},C.status||403);let S=await g.req.json().catch(()=>({})),E="";s&&(E=await Oa({type:"preview",collection:l.slug,id:S.id,exp:Math.floor(Date.now()/1e3)+3600},s,"HS256"));let D="";if(l.admin?.preview){D=await l.admin.preview(S,{req:g.req.raw,token:E});try{let P=new URL(D,"http://localhost");P.searchParams.has("preview")||P.searchParams.set("preview","true"),!P.searchParams.has("kyroToken")&&E&&P.searchParams.set("kyroToken",E),D=D.startsWith("http")?P.toString():`${P.pathname}${P.search}`;}catch{}}else {let P="";try{let N=await r.findOne({collection:"_globals_site-settings",where:{}});N?.siteUrl&&(P=N.siteUrl);}catch{}if(!P)return g.json({error:"No site URL configured in settings, and no custom preview function defined for this collection."},400);P=P.replace(/\/$/,"");let j=S.slug||S.id||"";D=`${P}/${l.slug}/${j}?preview=true&kyroToken=${E}`;}return g.json({url:D})}catch(f){return g.json({error:f.message},500)}}),w.post(v,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"create",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);_&&r.setTenantContext({tenantId:_,userId:f?.id??"",role:f?.role,isSuperAdmin:f?.role==="super_admin"}),Nc(V,C,v,"POST",g.req.raw);let D=await g.req.json();es(D,l.fields),ts(l.fields,D);let P=g.req.raw;if(l.hooks?.beforeValidate)for(let J of l.hooks.beforeValidate){let ye=await J({collection:y,data:D,req:P,user:f,tenantId:_,operation:"create"});ye&&typeof ye=="object"&&!Array.isArray(ye)&&Object.assign(D,ye);}let j=e.getCreateZodSchema(y);try{D=j.parse(D);}catch(J){return g.json({error:`Validation failed: ${fo(J.errors)}`,details:J.errors},400)}l.tenantScoped&&_&&(D.tenantId=_);let N=l.versions?.drafts===!0,z=l.fields.find(J=>J.name==="status"),Y=z?.type==="select"&&Array.isArray(z.options)&&z.options.some(J=>J.value==="published");if(N?D.status="draft":Y&&!D.status&&(D.status="published"),l.hooks?.beforeChange)for(let J of l.hooks.beforeChange){let ye=await J({collection:y,data:D,req:P,user:f,tenantId:_,operation:"create"});ye&&typeof ye=="object"&&!Array.isArray(ye)&&Object.assign(D,ye);}let ue=await r.create({collection:y,data:D,tenantId:_});if(N&&await r.createVersion({collection:y,documentId:ue.id,data:D,status:"draft",createdBy:f?.id,changeDescription:"Created",tenantId:_}),l.hooks?.afterChange)for(let J of l.hooks.afterChange)await J({collection:y,doc:ue,data:D,req:P,user:f,tenantId:_,operation:"create"});return d&&d.trigger(la(y,"create"),{collection:y,operation:"create",data:ue,user:f?{id:f.id,email:f.email,role:f.role}:void 0,tenantId:_}).catch(J=>console.error("[Webhook] Failed to trigger:",J)),f&&V?.createAuditLog({action:"document_create",userId:f.id,resource:y,resourceId:ue.id,success:!0}),g.json({data:ue,message:"Created successfully"},201)}catch(f){return f.name==="ZodError"?g.json({error:`Validation failed: ${fo(f.errors)}`,details:f.errors},400):g.json({error:f.message},500)}}),w.patch(`${v}/:id`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"update",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=g.req.param("id"),D=await g.req.json(),P=Mc(D),j=await r.findByID({collection:y,id:E,tenantId:_,draft:!0});if(!j)return g.json({error:"Document not found"},404);if(P&&j.updatedAt&&P!==j.updatedAt)return g.json(Fd(P,j),409);let N=Object.fromEntries(Object.entries(qd(D)).filter(([Nt,Xe])=>Xe!=="null"&&Xe!==void 0));es(N,l.fields),ts(l.fields,N);let z=g.req.raw;if(l.hooks?.beforeValidate)for(let Nt of l.hooks.beforeValidate){let Xe=await Nt({collection:y,data:N,originalDoc:j,req:z,user:f,tenantId:_,operation:"update"});Xe&&typeof Xe=="object"&&!Array.isArray(Xe)&&Object.assign(N,Xe);}if(N=e.getUpdateZodSchema(y).parse(N),l.hooks?.beforeChange)for(let Nt of l.hooks.beforeChange){let Xe=await Nt({collection:y,data:N,originalDoc:j,req:z,user:f,tenantId:_,operation:"update"});Xe&&typeof Xe=="object"&&!Array.isArray(Xe)&&Object.assign(N,Xe);}let ue=g.req.header("X-Draft")==="true",J=l.versions?.drafts===!0,ye=g.req.query("autosave")==="true",Je;if(J&&ue?await r.createVersion({collection:y,documentId:E,data:N,status:"draft",autosave:ye,createdBy:f?.id,changeDescription:ye?"Autosave":"Draft saved",tenantId:_}):J?(await r.update({collection:y,id:E,data:{...N,status:"published"},tenantId:_}),await r.createVersion({collection:y,documentId:E,data:N,status:"published",createdBy:f?.id,changeDescription:"Published",tenantId:_})):await r.update({collection:y,id:E,data:N,tenantId:_}),Je=await r.findByID({collection:y,id:E,tenantId:_,draft:!0}),l.hooks?.afterChange)for(let Nt of l.hooks.afterChange)await Nt({collection:y,doc:Je,data:N,originalDoc:j,req:z,user:f,tenantId:_,operation:"update"});return d&&!ye&&d.trigger(la(y,"update"),{collection:y,operation:"update",data:Je,previousData:j,user:f?{id:f.id,email:f.email,role:f.role}:void 0,tenantId:_}).catch(Nt=>console.error("[Webhook] Failed to trigger:",Nt)),Nc(V,C,`${v}/${E}`,"PATCH",g.req.raw),f&&V?.createAuditLog({action:"document_update",userId:f.id,resource:y,resourceId:E,success:!0}),g.json({data:Je,message:J?"Draft saved":"Updated successfully"})}catch(f){return f.name==="ZodError"?(console.error(`[PATCH ${v}/:id] Validation failed:`,f.errors),g.json({error:`Validation failed: ${fo(f.errors)}`,details:f.errors},400)):(console.error(`[PATCH ${v}/:id] ERROR:`,f.message,"CAUSE:",f.cause?.message||f.cause,"QUERY:",f.query),g.json({error:f.message},500))}}),w.delete(`${v}/:id`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"delete",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);_&&r.setTenantContext({tenantId:_,userId:f?.id??"",role:f?.role,isSuperAdmin:f?.role==="super_admin"});let E=g.req.param("id"),D=g.req.raw,P=await r.findByID({collection:y,id:E,tenantId:_,draft:!0});if(!P)return g.json({error:"Document not found"},404);if(l.hooks?.beforeDelete)for(let N of l.hooks.beforeDelete)await N({collection:y,doc:P,req:D,user:f,tenantId:_,operation:"delete"});let j=await r.delete({collection:y,id:E,tenantId:_});if(l.hooks?.afterDelete)for(let N of l.hooks.afterDelete)await N({collection:y,doc:j,originalDoc:P,req:D,user:f,tenantId:_,operation:"delete"});return d&&d.trigger(la(y,"delete"),{collection:y,operation:"delete",data:j,previousData:P,user:f?{id:f.id,email:f.email,role:f.role}:void 0,tenantId:_}).catch(N=>console.error("[Webhook] Failed to trigger:",N)),Nc(V,C,`${v}/${E}`,"DELETE",g.req.raw),f&&V?.createAuditLog({action:"document_delete",userId:f.id,resource:y,resourceId:E,success:!0}),g.json({data:j,message:"Deleted successfully"})}catch(f){return console.error(`[DELETE] Error deleting ${y}:`,f),g.json({error:f.message||String(f)},500)}}),w.post(`${v}/:id/duplicate`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"create",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=g.req.param("id"),D=await r.findByID({collection:y,id:E,tenantId:_,draft:!0});if(!D)return g.json({error:"Document not found"},404);let{id:P,createdAt:j,updatedAt:N,...z}=D;Ws(l.fields,z);let Y=Date.now().toString(36);"slug"in z&&typeof z.slug=="string"&&(z.slug=`${z.slug||"document"}-copy-${Y}`),"title"in z&&typeof z.title=="string"?z.title=`${z.title||"Copy"} (Copy)`:"name"in z&&typeof z.name=="string"&&(z.name=`${z.name||"Copy"} (Copy)`);let ue=await r.create({collection:y,data:{...z,status:"draft"},tenantId:_});return g.json({data:ue,message:"Document duplicated successfully"})}catch(f){return console.error("[Duplicate] Error:",f),g.json({error:f.message||String(f)},500)}}),w.post(`${v}/:id/versions/:versionId/restore`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"update",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=g.req.param("id"),D=g.req.param("versionId"),P=await r.findVersionByID({collection:y,versionId:D,tenantId:_});if(!P)return g.json({error:"Version not found"},404);let j=await r.update({collection:y,id:E,data:{...P.data,status:"draft"},tenantId:_});return g.json({data:j,message:"Version restored successfully"})}catch(f){return g.json({error:f.message},500)}}),w.post(`${v}/:id/versions`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"update",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=await g.req.json(),{versionId:D,action:P}=E;if(P==="restore"&&D){let j=await r.findVersionByID({collection:y,versionId:D,tenantId:_});if(!j)return g.json({error:"Version not found"},404);let N=await r.update({collection:y,id:g.req.param("id"),data:{...j.data,status:"draft"},tenantId:_});return g.json({data:N,message:"Version restored successfully"})}return g.json({error:"Invalid action"},400)}catch(f){return g.json({error:f.message},500)}}),w.post(`${v}/:id/publish`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"update",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);_&&r.setTenantContext({tenantId:_,userId:f?.id??"",role:f?.role,isSuperAdmin:f?.role==="super_admin"});let E=g.req.param("id"),D=await g.req.json().catch(()=>({})),P=Mc(D),j=await r.findByID({collection:y,id:E,tenantId:_,draft:!0});if(!j)return g.json({error:"Document not found"},404);if(P&&j.updatedAt&&P!==j.updatedAt)return g.json(Fd(P,j),409);let N={status:"published"},z=j;if(l.versions?.drafts){let ue=await r.findVersions({collection:y,documentId:E,limit:1,sort:"-createdAt",tenantId:_});if(ue.docs.length>0){let J=ue.docs[0];z={...j,...J.data},N={...J.data,...N};}}let Y=await r.update({collection:y,id:E,data:N,tenantId:_});return l.versions?.drafts&&await r.createVersion({collection:y,documentId:E,data:{...z,status:"published"},status:"published",createdBy:f?.id,changeDescription:"Published",tenantId:_}),d&&d.trigger(la(y,"update"),{collection:y,operation:"update",data:Y,user:f?{id:f.id,email:f.email,role:f.role}:void 0,tenantId:_}).catch(ue=>console.error("[Webhook] Failed to trigger:",ue)),g.json({data:Y,message:"Published successfully"})}catch(f){return g.json({error:f.message},500)}}),w.post(`${v}/:id/unpublish`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"update",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=g.req.param("id");if(!await r.findByID({collection:y,id:E,tenantId:_,draft:!0}))return g.json({error:"Document not found"},404);let P=await r.update({collection:y,id:E,data:{status:"draft"},tenantId:_});return d&&d.trigger(la(y,"update"),{collection:y,operation:"update",data:P,user:f?{id:f.id,email:f.email,role:f.role}:void 0,tenantId:_}).catch(j=>console.error("[Webhook] Failed to trigger:",j)),g.json({data:P,message:"Unpublished successfully"})}catch(f){return g.json({error:f.message},500)}});}for(let l of e.getGlobals()){let y=l.slug,v=`/api/globals/${y}`;w.post(`${v}/dynamic-options/:fieldName`,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await tr(l,"read",g.req.raw,f,_,O);if(!C.allowed)return g.json({error:C.error},C.status||403);let S=g.req.param("fieldName"),E=await g.req.json(),{data:D,siblingData:P}=E,j=vs(l.fields,S);if(!j)return g.json({error:"Field not found"},404);if(j.type!=="select")return g.json({error:"Field is not a select field"},400);let N=[];return typeof j.options=="function"?N=await j.options({data:D||{},siblingData:P||{}}):Array.isArray(j.options)&&(N=j.options),g.json({options:N})}catch(f){return g.json({error:f.message},500)}}),w.get(v,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=new URL(g.req.url),S=C.searchParams.get("kyroToken"),E=C.searchParams.get("draft"),D=!1;if(E==="true"&&S&&s)try{let Y=await Pa(S,s,"HS256");Y&&Y.type==="preview"&&Y.collection===`_globals_${l.slug}`&&(D=!0);}catch(Y){console.warn("Invalid preview token",Y);}if(!D){let Y=await tr(l,"read",g.req.raw,f,_,O);if(!Y.allowed)return g.json({error:Y.error},Y.status||403)}let P=E==="true"?!0:E==="false"?!1:!!f,j=parseInt(C.searchParams.get("depth")||"0"),z=(await r.find({collection:`_globals_${y}`,where:{},tenantId:_,draft:P,depth:j,limit:1})).docs[0];if(z&&j>0&&await chunkAK754S3T_cjs.a([z],l.fields,r,e,1,j),y==="storage-settings"&&(typeof globalThis.STORAGE_BUCKET<"u"||typeof g.env?.STORAGE_BUCKET<"u")&&(z?z.provider||(z.provider="cloudflare_r2"):z={id:y,provider:"cloudflare_r2"}),y==="system"){let Y=lv__default.default.randomBytes(32).toString("hex");z?z.appSecret||(await r.update({collection:`_globals_${y}`,id:y,data:{appSecret:Y},tenantId:_}),z.appSecret=Y):z=await r.create({collection:`_globals_${y}`,data:{id:y,appSecret:Y},tenantId:_});}return g.json({data:z||{}})}catch(f){return g.json({error:f.message},500)}});let R=async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await tr(l,"update",g.req.raw,f,_,O);if(!C.allowed)return g.json({error:C.error},C.status||403);let S=new URL(g.req.url),E=parseInt(S.searchParams.get("depth")||"0"),D=await g.req.json(),P=Mc(D),j=qd(D),N=Object.fromEntries(Object.entries(j).filter(([It,js])=>js!==null&&js!=="null"&&js!==void 0));es(N,l.fields),ts(l.fields,N);let z=e.getUpdateZodSchema(y),Y;try{Y=z.parse(N);}catch(It){return g.json({error:`Validation failed: ${fo(It.errors)}`,details:It.errors},400)}let ue=new Set(["id","createdAt","updatedAt","status","baseUpdatedAt","_baseUpdatedAt"]),J=Object.fromEntries(Object.entries(Y).filter(([It])=>!ue.has(It))),ye=`_globals_${y}`,Je=await r.findOne({collection:ye,where:{},tenantId:_,draft:!0});if(Je&&P&&Je.updatedAt&&P!==Je.updatedAt)return g.json(Fd(P,Je),409);let Nt=g.req.header("X-Draft")==="true",Xe=l.versions?.drafts===!0,Xr=g.req.query("autosave")==="true",St;if(Xe&&Nt)await r.createVersion({collection:ye,documentId:y,data:J,status:"draft",autosave:Xr,createdBy:f?.id,changeDescription:Xr?"Autosave":"Manual save",tenantId:_}),Je?St=Je:St=await r.create({collection:ye,data:{...J,id:y,status:"draft"},tenantId:_});else if(Xe&&!Nt){let It="published";Je?St=await r.update({collection:ye,id:y,data:{...J,status:It},tenantId:_}):St=await r.create({collection:ye,data:{...J,id:y,status:It},tenantId:_}),await r.createVersion({collection:ye,documentId:y,data:J,status:It,autosave:!1,createdBy:f?.id,changeDescription:"Published",tenantId:_});}else Je?St=await r.update({collection:ye,id:y,data:J,tenantId:_}):St=await r.create({collection:ye,data:{...J,id:y},tenantId:_});if(y==="storage-settings"&&(Bt=null,$r=null),y==="email-settings"){let It=await chunkP7XYIKL6_cjs.k.fromConfig(r);Re.email=It||void 0;}return y==="system"&&await gm(),f&&V?.createAuditLog({action:"settings_change",userId:f.id,resource:`global:${y}`,resourceId:y,success:!0}),St&&E>0&&await chunkAK754S3T_cjs.a([St],l.fields,r,e,1,E),g.json({data:St,message:"Updated successfully"})}catch(f){return console.error(`[API] Save global "${y}" failed:`,f),g.json({error:f.message||"Save failed",stack:process.env.NODE_ENV==="development"?f.stack:void 0},500)}};w.post(v,R),w.patch(v,R),w.post(`${v}/preview-url`,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await tr(l,"read",g.req.raw,f,_);if(!C.allowed)return g.json({error:C.error||"Forbidden"},C.status||403);let S=await g.req.json().catch(()=>({})),E="";s&&(E=await Oa({type:"preview",collection:`_globals_${l.slug}`,exp:Math.floor(Date.now()/1e3)+3600},s,"HS256"));let D="";if(l.admin?.preview)D=await l.admin.preview(S,{req:g.req.raw,token:E});else {let P="";try{let j=await r.findOne({collection:"_globals_site-settings",where:{}});j?.siteUrl&&(P=j.siteUrl);}catch{}if(!P)return g.json({error:"No site URL configured in settings, and no custom preview function defined."},400);P=P.replace(/\/$/,""),D=`${P}/?preview=true&kyroToken=${E}`;}return g.json({url:D})}catch(f){return g.json({error:f.message},500)}}),w.post(`${v}/publish`,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await tr(l,"update",g.req.raw,f,_,O);if(!C.allowed)return g.json({error:C.error},403);let S=`_globals_${y}`,E=await r.findOne({collection:S,where:{},tenantId:_,draft:!0});if(!E)return g.json({error:"Global not found"},404);let D={status:"published"},P=E;if(l.versions?.drafts){let N=await r.findVersions({collection:S,documentId:y,limit:1,sort:"-createdAt",tenantId:_});N.docs.length>0&&(P={...E,...N.docs[0].data},D={...N.docs[0].data,...D});}let j=await r.update({collection:S,id:y,data:D,tenantId:_});return l.versions?.drafts&&await r.createVersion({collection:S,documentId:y,data:{...P,status:"published"},status:"published",createdBy:f?.id,changeDescription:"Published",tenantId:_}),g.json({data:j,message:"Published successfully"})}catch(f){return g.json({error:f.message},500)}}),w.post(`${v}/unpublish`,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await tr(l,"update",g.req.raw,f,_,O);if(!C.allowed)return g.json({error:C.error},403);let S=await r.update({collection:`_globals_${y}`,id:y,data:{status:"draft"},tenantId:_});return g.json({data:S,message:"Unpublished successfully"})}catch(f){return g.json({error:f.message},500)}}),w.get(`${v}/versions`,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await tr(l,"read",g.req.raw,f,_,O);if(!C.allowed)return g.json({error:C.error},403);let S=parseInt(g.req.query("limit")||"10"),E=parseInt(g.req.query("page")||"1"),D=await r.findVersions({collection:`_globals_${y}`,documentId:y,limit:S,page:E,tenantId:_});return g.json(D)}catch(f){return g.json({error:f.message},500)}}),w.get(`${v}/versions/:versionId`,async g=>{try{let f=g.req.param("versionId"),{user:_,tenantId:C}=await W(g.req.raw,H,i,c),S=await tr(l,"read",g.req.raw,_,C,O);if(!S.allowed)return g.json({error:S.error},403);let E=await r.findVersionByID({collection:`_globals_${y}`,versionId:f,tenantId:C});return E?g.json({data:E}):g.json({error:"Version not found"},404)}catch(f){return g.json({error:f.message},500)}}),w.post(`${v}/versions/:versionId/restore`,async g=>{try{let f=g.req.param("versionId"),{user:_,tenantId:C}=await W(g.req.raw,H,i,c),S=await tr(l,"update",g.req.raw,_,C,O);if(!S.allowed)return g.json({error:S.error},403);let E=`_globals_${y}`,D=await r.findVersionByID({collection:E,versionId:f,tenantId:C});if(!D)return g.json({error:"Version not found"},404);let P=await r.update({collection:E,id:y,data:{...D.data,status:"draft"},tenantId:C});return g.json({data:P,message:"Version restored successfully"})}catch(f){return g.json({error:f.message},500)}}),y==="email-settings"&&w.post(`${v}/test`,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await tr(l,"update",g.req.raw,f,_,O);if(!C.allowed)return g.json({error:C.error},C.status||403);let S=await g.req.json(),E={provider:S.provider,from:S.fromEmail||S.from,fromName:S.fromName,replyTo:S.replyTo,smtp:S.smtp?{host:S.smtp.host,port:S.smtp.port,secure:S.smtp.secure,auth:{user:S.smtp.username||S.smtp.user,pass:S.smtp.password||S.smtp.pass}}:void 0,resend:S.resend,sendgrid:S.sendgrid,mailgun:S.mailgun,ses:S.ses},D=new chunkP7XYIKL6_cjs.k(E),P=S.email||S.testEmail||S.testEmailSection&&S.testEmailSection.testEmail;if(!P)return g.json({error:"No test recipient email provided"},400);let j=S.provider?S.provider.charAt(0).toUpperCase()+S.provider.slice(1):"SMTP",N=S.fromName?`${S.fromName} <${S.fromEmail||S.from||"default"}>`:S.fromEmail||S.from||"Configured Sender",z=new Date().toUTCString();return await D.send({to:P,subject:"Kyro CMS \u2014 Email Connection Test",html:`<!DOCTYPE html>
124
+ `).map(l=>l.trim()).filter(Boolean):[],Fe=Lr.length>0?Lr:gs||[];(Fe.length>0||p)&&w.use("*",async(l,y)=>{let v=l.req.header("Origin")||"*";if(Fe.length>0&&!Fe.includes(v))return l.json({error:"Origin not allowed"},403);let R=Fe.length>0?v:"*";if(l.header("Access-Control-Allow-Origin",R),l.header("Access-Control-Allow-Methods","GET, POST, PATCH, DELETE, OPTIONS"),l.header("Access-Control-Allow-Headers","Content-Type, Authorization, X-API-Key"),p?.credentials&&l.header("Access-Control-Allow-Credentials","true"),l.req.method==="OPTIONS")return l.text("");await y();});let gr=x?.access?.rateLimiting,rr;if(gr?.enabled){let l=gr.maxRequests||100,y=gr.windowMs||6e4;rr=new Ma({"api:general":{window:y,max:l}}),w.use("/api/*",async(v,R)=>{if(!rr)return R();let g=v.req.header("CF-Connecting-IP")||v.req.header("X-Forwarded-For")?.split(",")[0]?.trim()||v.req.header("X-Real-IP")||"unknown",f=await rr.check("api:general",g);if(v.header("X-RateLimit-Limit",String(l)),v.header("X-RateLimit-Remaining",String(f.remaining)),v.header("X-RateLimit-Reset",String(f.resetAt)),!f.allowed)return v.json({error:"Too many requests",retryAfter:f.retryAfter},429);await R();});}let Re=new Ua({redis:V,jwtSecret:s||"change-me",baseUrl:process.env.KYRO_BASE_URL||"http://localhost:4321",rateLimiter:rr});chunkP7XYIKL6_cjs.k.fromConfig(r).then(l=>{l&&(Re.email=l);}).catch(l=>{console.error("[Email] Failed to initialize transport from config:",l);}),w.post("/api/auth/login",async l=>Re.login(l.req.raw)),w.post("/api/auth/register",async l=>{try{let y=await r.findOne({collection:"_globals_system",where:{}});if(y&&y.enableRegistration===!1)return l.json({error:"User registration is currently disabled by administrator."},403);if(y?.defaultRegistrationRole){let v=l.req.raw;if((v.headers.get("content-type")||"").includes("application/json")){let g=await l.req.json();g.role||(g.role=y.defaultRegistrationRole);let f=new Request(v.url,{method:v.method,headers:v.headers,body:JSON.stringify(g)});return Re.register(f)}}}catch{}return Re.register(l.req.raw)}),w.post("/api/auth/logout",async l=>Re.logout(l.req.raw)),w.post("/api/auth/refresh",async l=>Re.refresh(l.req.raw)),w.get("/api/auth/me",async l=>Re.me(l.req.raw)),w.post("/api/auth/forgot-password",async l=>Re.forgotPassword(l.req.raw)),w.post("/api/auth/reset-password",async l=>Re.resetPassword(l.req.raw)),w.post("/api/auth/change-password",async l=>Re.changePassword(l.req.raw)),w.get("/api/auth/verify-email",async l=>Re.verifyEmail(l.req.raw)),w.post("/api/auth/verify-email",async l=>Re.verifyEmail(l.req.raw)),w.get("/api/auth/verify",async l=>Re.verifyEmail(l.req.raw)),w.post("/api/auth/verify",async l=>Re.verifyEmail(l.req.raw)),w.get("/api/auth/sessions",async l=>Re.listSessions(l.req.raw)),w.post("/api/auth/sessions/refresh",async l=>Re.refreshSession(l.req.raw)),w.delete("/api/auth/sessions",async l=>Re.revokeOtherSessions(l.req.raw)),w.delete("/api/auth/sessions/:id",async l=>Re.revokeSession(l.req.raw,l.req.param("id"))),w.put("/api/auth/sessions/:id/name",async l=>Re.renameSession(l.req.raw,l.req.param("id"))),w.get("/api/auth/access",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Not authenticated"},401);let R={},g={};for(let f of e.getCollections()){let _={read:(await Ie(f,"read",l.req.raw,y,v,void 0,O,F)).allowed,create:(await Ie(f,"create",l.req.raw,y,v,void 0,O,F)).allowed,update:(await Ie(f,"update",l.req.raw,y,v,void 0,O,F)).allowed,delete:(await Ie(f,"delete",l.req.raw,y,v,void 0,O,F)).allowed};R[f.slug]=_;}for(let f of e.getGlobals()){let _={read:(await tr(f,"read",l.req.raw,y,v,O)).allowed,update:(await tr(f,"update",l.req.raw,y,v,O)).allowed};g[f.slug]=_;}return l.json({collections:R,globals:g})}catch(y){return l.json({error:y.message},500)}});let $t=typeof e.hasCollection=="function"&&e.hasCollection("users")?e.getCollection("users"):(()=>{try{return e.getCollection("users")}catch{return chunkZO3YB5DK_cjs.a}})();w.get("/api/users",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c),R=await Ie($t,"read",l.req.raw,y,v,void 0,O,F);if(!R.allowed)return l.json({error:R.error},R.status||403);let g=parseInt(l.req.query("page")||"1"),f=Math.min(parseInt(l.req.query("limit")||"10"),100),_=l.req.query("search")||void 0,C=[],S=0;if(typeof V.findUsers=="function"){let E=await V.findUsers({page:g,limit:f,search:_});C=E.users||[],S=E.total||0;}else {let E=await r.find({collection:"users",page:g,limit:f,where:_?{email:{contains:_}}:{},tenantId:v});C=E.docs||[],S=E.totalDocs||0;}return l.json({docs:C,totalDocs:S,limit:f,totalPages:Math.ceil(S/f)||1,page:g,pagingCounter:(g-1)*f+1,hasPrevPage:g>1,hasNextPage:g<Math.ceil(S/f),prevPage:g>1?g-1:null,nextPage:g<Math.ceil(S/f)?g+1:null})}catch(y){return console.error("[API] Error listing users:",y),l.json({error:y.message},500)}}),w.get("/api/users/:id",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c),R=l.req.param("id"),g=await V.findUserById(R);return g?l.json({data:g}):l.json({error:"User not found"},404)}catch(y){return l.json({error:y.message},500)}}),w.post("/api/users",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c),R=await Ie($t,"create",l.req.raw,y,v,void 0,O,F);if(!R.allowed)return l.json({error:R.error},R.status||403);let g=await l.req.json();if(!g.email||!g.password)return l.json({error:"Email and password are required"},400);if(await V.findUserByEmail(g.email))return l.json({error:"Email already in use"},400);let _=g.role||"customer";if(_!=="customer"&&y?.role!=="super_admin")return l.json({error:"Forbidden: Only super_admin can assign administrative roles"},403);let C=await V.createUser({email:g.email,password:g.password,name:g.name,role:_,avatar:g.avatar,tenantId:g.tenantId});return y&&V?.createAuditLog({action:"user_create",userId:y.id,resource:"users",resourceId:C.id,success:!0}),l.json({data:C,message:"User created successfully"},201)}catch(y){return l.json({error:y.message},500)}}),w.patch("/api/users/:id",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c),R=await Ie($t,"update",l.req.raw,y,v,void 0,O,F);if(!R.allowed)return l.json({error:R.error},R.status||403);let g=l.req.param("id"),f=await l.req.json(),_=await V.findUserById(g);if(!_)return l.json({error:"User not found"},404);let C={};if(f.name!==void 0&&(C.name=f.name),f.email!==void 0&&(C.email=f.email),f.role!==void 0&&f.role!==_.role){if(y?.role!=="super_admin")return l.json({error:"Forbidden: Only super_admin can modify user roles"},403);C.role=f.role;}f.avatar!==void 0&&(C.avatar=typeof f.avatar=="object"&&f.avatar!==null?f.avatar.id||String(f.avatar):f.avatar),f.tenantId!==void 0&&(C.tenantId=f.tenantId),f.emailVerified!==void 0&&(C.emailVerified=f.emailVerified),f.locked!==void 0&&(C.locked=f.locked),f.failedLoginAttempts!==void 0&&(C.failedLoginAttempts=f.failedLoginAttempts),f.lastLogin!==void 0&&(C.lastLogin=f.lastLogin);let S=await V.updateUser(g,C);return S?(y&&(V?.createAuditLog({action:"user_update",userId:y.id,resource:"users",resourceId:g,success:!0}),f.role&&_.role!==f.role&&V?.createAuditLog({action:"role_change",userId:y.id,resource:"users",resourceId:g,success:!0,metadata:{oldRole:_.role,newRole:f.role}})),l.json({data:S,message:"User updated successfully"})):l.json({error:"User update failed"},500)}catch(y){return l.json({error:y.message},500)}}),w.delete("/api/users/:id",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c),R=await Ie($t,"delete",l.req.raw,y,v,void 0,O,F);if(!R.allowed)return l.json({error:R.error},R.status||403);let g=l.req.param("id");if(y&&y.id===g)return l.json({error:"You cannot delete your own account"},403);let f=await V.findUserById(g);return f?await V.deleteUser(g)?(y&&V?.createAuditLog({action:"user_delete",userId:y.id,resource:"users",resourceId:g,success:!0}),l.json({data:f,message:"User deleted successfully"})):l.json({error:"User deletion failed"},500):l.json({error:"User not found"},404)}catch(y){return l.json({error:y.message},500)}}),w.get("/api/auth/audit-logs",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c),R=e.getCollection("audit_logs");if(R){let D=await Ie(R,"read",l.req.raw,y,v,void 0,O,F);if(!D.allowed)return l.json({error:D.error},D.status||403)}else if(!y)return l.json({error:"Authentication required"},401);let g=parseInt(l.req.query("page")||"1"),f=Math.min(parseInt(l.req.query("limit")||"50"),100),_=l.req.query("action")||void 0,C=l.req.query("userId")||void 0,S=l.req.query("resource")||void 0,E=await V.findAuditLogs({action:_,userId:C,resource:S,limit:f,offset:(g-1)*f});return l.json({docs:E.logs,totalDocs:E.total,limit:f,totalPages:Math.ceil(E.total/f),page:g,pagingCounter:(g-1)*f+1,hasPrevPage:g>1,hasNextPage:g<Math.ceil(E.total/f),prevPage:g>1?g-1:null,nextPage:g<Math.ceil(E.total/f)?g+1:null})}catch(y){return console.error("[API] Error listing audit logs:",y),l.json({error:y.message},500)}});let Bt=null,$r=null,ht=async()=>{if($r)throw $r;if(!Bt)try{let l="sqlite";"dialect"in r&&r.dialect==="postgres"&&r instanceof chunk6KUL2BSA_cjs.c?l=r.dialect:"dialect"in r&&r.dialect==="mongodb"&&(l="mongodb");let y=l==="postgres"&&r instanceof chunk6KUL2BSA_cjs.c?r.client:r;Bt=await Tc.init(y,{dialect:l});}catch(l){throw console.error("[getMedia] Init error:",l),$r=l,l}return Bt};w.get("/api/media",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht(),R=new URL(l.req.url).origin,g=parseInt(l.req.query("page")||"1"),f=parseInt(l.req.query("limit")||"30"),_=l.req.query("search")||"",C=l.req.query("type")||"",S=l.req.query("folder")||"",E=await v.find({page:g,limit:f,search:_,type:C,folder:S},R);return l.json(E)}catch(y){return console.error("[Media] find error:",y),l.json({error:y.message},500)}}),w.post("/api/media/upload",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht(),R=l.req.header("content-type")||"",g=new URL(l.req.url).origin;if(R.includes("multipart/form-data")){let E=await l.req.formData(),D=E.get("file"),P=E.get("folder")||"";if(!D)return l.json({error:"No file uploaded"},400);let j=await v.upload(D,P,g);return l.json(j)}let f=await l.req.json(),{url:_}=f,C=f.folder||"";if(!_)return l.json({error:"No URL provided"},400);let S=await v.uploadFromUrl(_,C,g);return l.json(S)}catch(y){return console.error("[Media] upload error:",y),l.json({error:y.message},500)}}),w.get("/api/media/folders",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let R=await(await ht()).listFolders();return l.json(R)}catch(y){return console.error("[Media] folders error:",y),l.json({error:y.message},500)}}),w.post("/api/media/folders",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht(),R=await l.req.json(),{name:g,parentPath:f}=R;return g?(await v.createFolder(g,f||""),l.json({message:"Folder created",path:f?`${f}/${g}`:g})):l.json({error:"Folder name is required"},400)}catch(y){return console.error("[Media] create folder error:",y),l.json({error:y.message},500)}}),w.delete("/api/media/folders",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht(),R=l.req.query("path");return R?(await v.deleteFolder(R),l.json({message:"Folder deleted"})):l.json({error:"Path is required"},400)}catch(y){return console.error("[Media] delete folder error:",y),l.json({error:y.message},500)}}),w.delete("/api/media/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht(),R=l.req.param("id"),g=new URL(l.req.url).origin;return await v.delete(R,g),l.json({success:!0})}catch(y){return console.error("[Media] delete error:",y),l.json({error:y.message},500)}}),w.get("/api/media/file/:key{.+$}",async l=>{let y=l.req.param("key"),v=globalThis.STORAGE_BUCKET;if(v){let R=await v.get(y);if(!R)return l.notFound();let g=new Headers;return R.writeHttpMetadata(g),g.set("etag",R.httpEtag),new Response(R.body,{headers:g})}return l.notFound()}),w.get("/api/media/resize",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=l.req.query("url"),R=parseInt(l.req.query("w")||"0"),g=parseInt(l.req.query("h")||"0"),f=l.req.query("fit")||"cover",_=parseFloat(l.req.query("cx")||"0"),C=parseFloat(l.req.query("cy")||"0"),S=parseFloat(l.req.query("cw")||"0"),E=parseFloat(l.req.query("ch")||"0");if(!v)return l.json({error:"URL is required"},400);let P=(await ht()).storage;if(P.name!=="local")return l.redirect(v);let j=P.config?.uploadDir||Ga.join(process.cwd(),"public","uploads"),N=P.config?.baseUrl||"/uploads";if(!v.startsWith(N))return l.redirect(v);let z=v.replace(N,""),Y=Ga.join(j,z);if(!fs$1.existsSync(Y))return l.json({error:"File not found"},404);let ue=fs$1.readFileSync(Y),{default:J}=await import('sharp'),ye=J(ue);if(S>0&&E>0){let Xe=await J(ue).metadata(),Xr=Xe.width||0,St=Xe.height||0;if(Xr>0&&St>0){let It=Math.max(0,Math.min(Math.round(_/100*Xr),Xr-1)),js=Math.max(0,Math.min(Math.round(C/100*St),St-1)),I_=Math.max(1,Math.min(Math.round(S/100*Xr),Xr-It)),D_=Math.max(1,Math.min(Math.round(E/100*St),St-js));ye=ye.extract({left:It,top:js,width:I_,height:D_});}}(R>0||g>0)&&(ye=ye.resize({width:R>0?R:void 0,height:g>0?g:void 0,fit:f}));let Je=await ye.toBuffer(),Nt=await J(ue).metadata();return l.header("Content-Type",`image/${Nt.format||"webp"}`),l.header("Cache-Control","public, max-age=31536000, immutable"),l.body(Je)}catch(y){return console.error("[Media] resize error:",y),l.json({error:y.message},500)}}),w.get("/api/media/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht(),R=l.req.param("id"),g=new URL(l.req.url).origin,f=await v.findById(R,g);return f?l.json(f):l.json({error:"Media not found"},404)}catch(y){return console.error("[Media] get error:",y),l.json({error:y.message},500)}}),w.patch("/api/media/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht(),R=l.req.param("id"),g=await l.req.json(),f=new URL(l.req.url).origin,_=["folder","metadata","title","alt","caption","originalName"],C={};for(let S of _)g[S]!==void 0&&(C[S]=g[S]);if(Object.keys(C).length>0){let S=await v.update(R,C,f);return l.json({doc:S})}return l.json({error:"No valid fields to update"},400)}catch(y){return console.error("[Media] update error:",y),l.json({error:y.message},500)}}),w.get("/api/media/test",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=await ht();return l.json({status:v?"initialized":"failed",serviceType:v?.constructor?.name})}catch(y){return console.error("[test] Error:",y),l.json({error:y.message,type:y.constructor?.name,stack:y.stack},500)}}),w.get("/api/storage-status",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=typeof globalThis.STORAGE_BUCKET<"u"||typeof l.env?.STORAGE_BUCKET<"u",R=v,g=v?"cloudflare_r2":"local";if(r)try{let f=r.prepare('SELECT provider FROM "_globals_storage-settings" LIMIT 1').get();f&&f.provider&&(R=!0,g=f.provider==="aws"?"s3":f.provider);}catch{try{let f=await r.findOne({collection:"_globals_storage-settings",where:{},draft:!0});f&&f.provider&&(R=!0,g=f.provider==="aws"?"s3":f.provider);}catch{}}return l.json({provider:g,configured:R,usage:0,limit:"unlimited"})}catch(y){return console.error("[Storage] status error:",y),l.json({error:y.message},500)}}),w.get("/api/plugins",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=e.getPlugins(),R=e.storageProviders,g=await Promise.all(v.map(async f=>{let _=!0,C=f.name,S={};try{let P=await r.findOne({collection:"_globals_plugin-settings",where:{},draft:!0});P&&P.states&&(S=P.states);}catch{}S[C]!==void 0&&(_=S[C]),R.setPluginEnabled(C,_);let E=C.replace(/^@[^/]+\//,"");E=E.replace(/^(plugin|kyro)-/,"");let D={ai:"AI",seo:"SEO",s3:"S3",aws:"AWS",api:"API",ui:"UI",ftp:"FTP"};if(E=E.split("-").map(P=>{let j=P.toLowerCase();return D[j]?D[j]:P.charAt(0).toUpperCase()+P.slice(1)}).join(" "),E.toLowerCase().startsWith("storage ")){let P=E.split(" ");P.length===2&&(E=`${P[1]} Storage`);}return {id:C,name:f.displayName||E,version:f.version||"1.0.0",description:f.description||"",enabled:_,status:_?"active":"disabled"}}));return l.json(g)}catch(y){return console.error("[Plugins] list error:",y),l.json({error:y.message},500)}}),w.put("/api/plugins/:name/toggle",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=l.req.param("name"),R=e.storageProviders,f=!R.isPluginEnabled(v),_=[];if(!f)for(let S of R.getAll())S.pluginName===v&&_.push(S.type);if(!(l.req.query("force")==="1")&&!f&&_.length>0){let S="local";try{let E=r?.prepare?.('SELECT provider FROM "_globals_storage-settings" LIMIT 1')?.get();E?.provider&&(S=E.provider);}catch{try{let E=await r?.findOne?.({collection:"_globals_storage-settings",where:{},draft:!0});E?.provider&&(S=E.provider);}catch{}}if(_.includes(S))return l.json({error:`Cannot disable "${v}" \u2014 storage provider "${S}" is currently active. Switch to Local storage first.`,requiresAction:!0,activeProvider:S},409)}try{let S={},E="global",D=await r.findOne({collection:"_globals_plugin-settings",where:{},draft:!0});D&&(S=D.states||{},E=D.id),S[v]=f,D?await r.update({collection:"_globals_plugin-settings",id:E,data:{states:S}}):await r.create({collection:"_globals_plugin-settings",data:{states:S,id:"global"}});}catch(S){console.warn(`[Plugins] Could not persist state for "${v}":`,S);}return R.setPluginEnabled(v,f),l.json({name:v,enabled:f})}catch(y){return console.error("[Plugins] toggle error:",y),l.json({error:y.message},500)}}),w.get("/api/health",l=>l.json({status:"ok",version:"0.12.47",collections:e.getCollectionSlugs(),timestamp:new Date().toISOString()})),w.get("/api/metrics",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let R=y.role==="admin"||y.role==="super_admin",f=e.getCollectionSlugs().filter(N=>!["users","audit_logs","media","_globals_access-settings","_globals_brand-settings"].includes(N)&&!N.startsWith("_globals_")).filter(N=>R||chunk7WMMKGEO_cjs.a(y,`${N}:read`)),_=0,C={};await Promise.all(f.map(async N=>{try{let Y=(await r.find({collection:N,where:{},limit:1,page:1,tenantId:v})).totalDocs??0;_+=Y,C[N]=Y;}catch{}}));let S=0;try{S=(await r.find({collection:"media",where:{},limit:1,page:1,tenantId:v})).totalDocs??0;}catch{}let E=0;try{E=(await r.find({collection:"users",where:{},limit:1,page:1,tenantId:v})).totalDocs??0;}catch{}let D=0;try{if(d){let N=await d.getWebhooks();D=Array.isArray(N)?N.length:0;}}catch{}let P=0;try{P=(await r.find({collection:chunkDUO523BH_cjs.d,where:{},limit:1,page:1,tenantId:v})).totalDocs??0;}catch{}let j=_+S+E;return l.json({totalDocuments:_,totalMedia:R||chunk7WMMKGEO_cjs.a(y,"media:read")?S:void 0,totalUsers:R||chunk7WMMKGEO_cjs.a(y,"users:read")?E:void 0,totalWebhooks:R?D:void 0,totalApiKeys:R?P:void 0,totalStoredRecords:j,collectionCounts:C,collections:f.length,timestamp:new Date().toISOString()})}catch(y){return console.error("[API] Metrics error:",y),l.json({error:y.message},500)}}),w.get("/api/analytics",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);if(!(y.role==="admin"||y.role==="super_admin"))return l.json({error:"Unauthorized"},403);let f=(await r.find({collection:"orders",where:{},limit:1e3,page:1,tenantId:v})).docs||[],_=await r.findOne({collection:"_globals_store-settings",where:{},tenantId:v}),C=_?.currency?.code||_?.currency||"USD",S={},E={},D={};f.forEach(N=>{let z=N.createdAt||N.updatedAt,Y=z?new Date(z).toISOString().split("T")[0]:new Date().toISOString().split("T")[0];S[Y]||(S[Y]=0),E[Y]||(E[Y]=0);let ue=typeof N.total=="number"?N.total:parseFloat(String(N.total||0));S[Y]+=isNaN(ue)?0:ue,E[Y]+=1;let J=N.orderStatus||N.status||"pending";D[J]=(D[J]||0)+1;});let P=Object.keys(S).sort().map(N=>({date:N,revenue:Math.round(S[N]*100)/100,orders:E[N]})),j=Math.round(P.reduce((N,z)=>N+z.revenue,0)*100)/100;return l.json({chartData:P,totalRevenue:j,totalOrders:f.length,ordersByStatus:D,currencyCode:typeof C=="string"?C:"USD"})}catch(y){return l.json({error:y.message},500)}}),w.get("/api/kyro/schema",async l=>{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=g=>g.map(f=>{let _={name:f.name,type:f.type,label:f.label,required:f.required??false,unique:f.unique??false,indexed:f.indexed??false,defaultValue:f.defaultValue,admin:f.admin?{...f.admin}:void 0};return f.minLength!==void 0&&(_.minLength=f.minLength),f.maxLength!==void 0&&(_.maxLength=f.maxLength),f.pattern!==void 0&&(_.pattern=f.pattern),f.variant!==void 0&&(_.variant=f.variant),f.hasMany!==void 0&&(_.hasMany=f.hasMany),f.min!==void 0&&(_.min=f.min),f.max!==void 0&&(_.max=f.max),f.step!==void 0&&(_.step=f.step),f.integer!==void 0&&(_.integer=f.integer),f.options&&(_.options=f.options),f.relationTo&&(_.relationTo=f.relationTo),f.maxDepth!==void 0&&(_.maxDepth=f.maxDepth),f.minRows!==void 0&&(_.minRows=f.minRows),f.maxRows!==void 0&&(_.maxRows=f.maxRows),f.localized!==void 0&&(_.localized=f.localized),f.language&&(_.language=f.language),f.format&&(_.format=f.format),f.allowedTypes&&(_.allowedTypes=f.allowedTypes),f.maxSize&&(_.maxSize=f.maxSize),(f.type==="group"||f.type==="row"||f.type==="collapsible"&&f.fields)&&(_.fields=v(f.fields)),f.type==="array"&&f.fields&&(_.fields=v(f.fields)),f.type==="blocks"&&f.blocks&&(_.blocks=f.blocks.map(C=>({slug:C.slug,label:C.label,fields:v(C.fields)}))),f.type==="tabs"&&f.tabs&&(_.tabs=f.tabs.map(C=>({label:C.label,name:C.name,fields:v(C.fields)}))),_}),R={collections:{},globals:{}};for(let g of e.getCollections()){let f=g.slug;try{R.collections[f]={slug:f,label:g.label||f,fields:v(g.fields),jsonSchema:to(e.getZodSchema(f),{target:"openApi3"}),createSchema:to(e.getCreateZodSchema(f),{target:"openApi3"}),updateSchema:to(e.getUpdateZodSchema(f),{target:"openApi3"}),procedures:{find:{collection:f,where:"Record<string,any>",sort:"string",limit:"number",page:"number",depth:"number",select:"string[]",draft:"boolean"},findByID:{collection:f,id:"string",depth:"number",select:"string[]",draft:"boolean"},create:{collection:f,data:"Record<string,any>",depth:"number",select:"string[]"},update:{collection:f,id:"string",data:"Record<string,any>",depth:"number",select:"string[]",baseUpdatedAt:"string"},delete:{collection:f,id:"string"},count:{collection:f,where:"Record<string,any>"}}};}catch{}}for(let g of e.getGlobals()){let f=g.slug,_=g.fields;if(f==="storage-settings"){let C=e.storageProviders,S=C.getAll(),E=new Set(C.getAllAvailable(P=>C.isPluginEnabled(P)).map(P=>P.type));E.add("local");let D=new Set(S.map(P=>P.type));_=_.filter(P=>P.type==="group"&&P.name&&D.has(P.name)?E.has(P.name):true).map(P=>P.name==="provider"&&P.type==="select"?{...P,options:P.options.filter(j=>E.has(j.value))}:P);}try{R.globals[f]={slug:f,label:g.label||f,fields:v(_),jsonSchema:to(e.getZodSchema(f),{target:"openApi3"}),procedures:{get:{},update:{data:"Record<string,any>"}}};}catch{}}return l.json(R)}),w.get("/api/collections",async l=>{let{user:y}=await W(l.req.raw,H,i,c);if(!y)return l.json({error:"Authentication required"},401);let v=e.getCollections().map(R=>({slug:R.slug,label:R.label||R.slug,fields:R.fields.filter(g=>g.name).map(g=>({name:g.name,type:g.type,required:g.required,label:g.label}))}));return l.json(v)});function ro(l,y,v){if(v in y)return y[v];for(let R of l)if(R.name){if(R.type==="tabs"&&R.tabs){let g=y[R.name];if(g&&typeof g=="object"&&v in g)return g[v]}if((R.type==="group"||R.type==="collapsible")&&R.fields){let g=y[R.name];if(g&&typeof g=="object"){if(v in g)return g[v];let f=ro(R.fields,g,v);if(f!==void 0)return f}}}}w.get("/api/search",async l=>{try{let y=l.req.query("q")||"",v=l.req.query("collections")||"",R=Math.min(parseInt(l.req.query("limit")||"10"),50);if(!y||y.length<2)return l.json({results:[],message:"Query too short"});let{user:g,tenantId:f}=await W(l.req.raw,H,i,c),_=v?v.split(",").filter(Boolean):e.getCollectionSlugs(),C=[],S=new RegExp(y.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"i");for(let E of e.getCollections()){if(!_.includes(E.slug)||!(await Ie(E,"read",l.req.raw,g,f,void 0,O,F)).allowed)continue;let P=E.fields.filter(j=>j.name&&j.name!=="id"&&(j.type==="text"||j.type==="email"||j.type==="textarea"||j.type==="richtext"||j.indexed)&&!j.admin?.hidden).map(j=>j.name);if(P.length!==0)try{let j=P.map(z=>{let Y={};return Y[z]={like:`%${y}%`},Y}),N=await r.find({collection:E.slug,where:{OR:j},limit:R,tenantId:f});await chunkAK754S3T_cjs.a(N.docs,E.fields,r,e,1,0);for(let z of N.docs){let Y=E.admin?.useAsTitle||P.find(J=>J==="title"||J==="name"||J==="heading"||J==="slug"),ue=Y?ro(E.fields,z,Y)??z.id:z.id;C.push({collection:E.slug,label:E.label||E.slug,id:z.id,title:String(ue||"Untitled"),doc:z});}}catch(j){console.error(`Search error for ${E.slug}:`,j);}}return C.sort((E,D)=>E.label.localeCompare(D.label)),l.json({results:C})}catch(y){return l.json({error:y.message,results:[]},500)}}),w.get("/api/keys",async l=>{try{let{user:y,tenantId:v}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:read"))return l.json({error:"Forbidden"},403);let R=parseInt(l.req.query("page")||"1"),g=Math.min(parseInt(l.req.query("limit")||"50"),100),f=await r.find({collection:chunkDUO523BH_cjs.d,where:{},page:R,limit:g,tenantId:v}),_=(f.docs||[]).map(C=>({id:C.id,name:C.name,keyPrefix:C.keyPrefix,permissions:C.permissions||[],lastUsed:C.lastUsedAt,createdAt:C.createdAt}));return l.json({docs:_,totalDocs:f.totalDocs||_.length,totalPages:f.totalPages||1})}catch(y){return console.error("[ApiKeys] GET error:",y),l.json({error:y.message},500)}}),w.post("/api/keys",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);let v=await l.req.json();if(!v.name||typeof v.name!="string")return l.json({error:"name is required"},400);let R=chunkDUO523BH_cjs.i(),g=await r.create({collection:chunkDUO523BH_cjs.d,data:{userId:y.id,name:v.name,key:R,keyPrefix:chunkDUO523BH_cjs.j(R),permissions:Array.isArray(v.permissions)?v.permissions:["*"],expiresAt:v.expiresAt||null,createdAt:new Date().toISOString()}});return await V?.createAuditLog({action:"api_key_create",userId:y.id,resource:"api_key",resourceId:g.id,success:!0,metadata:{keyName:v.name}}),l.json({...g,key:R,permissions:Array.isArray(v.permissions)?v.permissions:["*"]},201)}catch(y){return console.error("[ApiKeys] POST error:",y),l.json({error:y.message},500)}}),w.delete("/api/keys/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);let v=l.req.param("id"),R=await r.findByID({collection:chunkDUO523BH_cjs.d,id:v});return R?(await r.delete({collection:chunkDUO523BH_cjs.d,id:v}),await V?.createAuditLog({action:"api_key_delete",userId:y.id,resource:"api_key",resourceId:v,success:!0,metadata:{keyName:R.name}}),l.json({message:"API key deleted"})):l.json({error:"API key not found"},404)}catch(y){return console.error("[ApiKeys] DELETE error:",y),l.json({error:y.message},500)}}),w.patch("/api/keys/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);let v=l.req.param("id"),R=await l.req.json(),g=await r.findByID({collection:chunkDUO523BH_cjs.d,id:v});if(!g)return l.json({error:"API key not found"},404);let f={};if(typeof R.name=="string"&&R.name.trim()&&(f.name=R.name.trim()),Array.isArray(R.permissions)&&(f.permissions=R.permissions),R.expiresAt!==void 0&&(f.expiresAt=R.expiresAt||null),Object.keys(f).length===0)return l.json({error:"Nothing to update"},400);let _=await r.update({collection:chunkDUO523BH_cjs.d,id:v,data:f});return l.json({..._,keyPrefix:g.keyPrefix})}catch(y){return console.error("[ApiKeys] PATCH error:",y),l.json({error:y.message},500)}}),w.post("/api/keys/:id/rotate",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);let v=l.req.param("id"),R=await r.findByID({collection:chunkDUO523BH_cjs.d,id:v});if(!R)return l.json({error:"API key not found"},404);let g=chunkDUO523BH_cjs.i(),f=await r.update({collection:chunkDUO523BH_cjs.d,id:v,data:{key:g,keyPrefix:chunkDUO523BH_cjs.j(g),lastUsedAt:null}});return await V?.createAuditLog({action:"api_key_rotate",userId:y.id,resource:"api_key",resourceId:v,success:!0,metadata:{keyName:R.name}}),l.json({...f,key:g,permissions:R.permissions,expiresAt:R.expiresAt})}catch(y){return console.error("[ApiKeys] rotate error:",y),l.json({error:y.message},500)}}),w.get("/api/webhooks/actions",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:read"))return l.json({error:"Forbidden"},403);let v={generic:{label:"Custom URL",description:"POST to any endpoint with Kyro payload",configFields:[],envVars:[]},"github-push":{label:"GitHub Push",description:"Push an empty commit to simulate a push event",configFields:[{name:"githubOwner",label:"Owner",required:!0,placeholder:"e.g., kyro-dev"},{name:"githubRepo",label:"Repository",required:!0,placeholder:"e.g., my-website"},{name:"githubBranch",label:"Branch",required:!1,placeholder:"main"}],envVars:["GITHUB_TOKEN"]}};return l.json({actions:v})}catch(y){return console.error("[Webhooks] actions error:",y),l.json({error:y.message},500)}}),w.get("/api/webhooks",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:read"))return l.json({error:"Forbidden"},403);if(!d)return l.json({error:"Webhook service not available"},503);let v=await d.getWebhooks();return l.json({docs:v})}catch(y){return console.error("[Webhooks] GET error:",y),l.json({error:y.message},500)}}),w.post("/api/webhooks",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);if(!d)return l.json({error:"Webhook service not available"},503);let v=await l.req.json(),R=await d.createWebhook(v);return await V?.createAuditLog({action:"webhook_create",userId:y.id,resource:"webhook",resourceId:R.id,success:!0,metadata:{name:R.name,url:R.url}}),l.json(R,201)}catch(y){return console.error("[Webhooks] POST error:",y),l.json({error:y.message},500)}}),w.get("/api/webhooks/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:read"))return l.json({error:"Forbidden"},403);if(!d)return l.json({error:"Webhook service not available"},503);let v=l.req.param("id"),R=await d.getWebhookById(v);return R?l.json(R):l.json({error:"Webhook not found"},404)}catch(y){return console.error("[Webhooks] GET :id error:",y),l.json({error:y.message},500)}}),w.patch("/api/webhooks/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);if(!d)return l.json({error:"Webhook service not available"},503);let v=l.req.param("id"),R=await l.req.json(),g=await d.updateWebhook(v,R);return g?(await V?.createAuditLog({action:"webhook_update",userId:y.id,resource:"webhook",resourceId:v,success:!0,metadata:{name:g.name}}),l.json(g)):l.json({error:"Webhook not found"},404)}catch(y){return console.error("[Webhooks] PATCH error:",y),l.json({error:y.message},500)}}),w.delete("/api/webhooks/:id",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);if(!d)return l.json({error:"Webhook service not available"},503);let v=l.req.param("id"),R=await d.getWebhookById(v);return R?(await d.deleteWebhook(v),await V?.createAuditLog({action:"webhook_delete",userId:y.id,resource:"webhook",resourceId:v,success:!0,metadata:{name:R.name}}),l.json({message:"Webhook deleted"})):l.json({error:"Webhook not found"},404)}catch(y){return console.error("[Webhooks] DELETE error:",y),l.json({error:y.message},500)}}),w.post("/api/webhooks/:id/test",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:admin"))return l.json({error:"Forbidden"},403);if(!d)return l.json({error:"Webhook service not available"},503);let v=l.req.param("id"),R=await d.testWebhook(v);return R?l.json(R):l.json({error:"Webhook not found"},404)}catch(y){return console.error("[Webhooks] test error:",y),l.json({error:y.message},500)}}),w.get("/api/webhooks/:id/history",async l=>{try{let{user:y}=await W(l.req.raw,H,i,c);if(!y||!chunk7WMMKGEO_cjs.a(y,"users:read"))return l.json({error:"Forbidden"},403);if(!d)return l.json({error:"Webhook service not available"},503);let v=l.req.param("id"),R=Math.min(parseInt(l.req.query("limit")||"50"),100),g=await d.getDeliveryHistory(v,R);return l.json({docs:g})}catch(y){return console.error("[Webhooks] history error:",y),l.json({error:y.message},500)}});function so(l){let y={},v=["name","type","required","hasMany","relationTo","options","min","max","minLength","maxLength","defaultValue","label","localized","admin","unique","index","hidden","readOnly","deprecated"];for(let R of v)R in l&&(y[R]=l[R]);return l.fields&&(y.fields=l.fields.map(so)),l.tabs&&(y.tabs=l.tabs.map(R=>({label:R.label,name:R.name,fields:R.fields.map(so)}))),y}w.get("/api/__schema",async l=>{try{let{user:y,apiKeyContext:v}=await W(l.req.raw,H,i,c);if(!y&&!v)return l.json({error:"Unauthorized"},401);let g=e.getCollections().filter(f=>f.slug!=="users"&&f.slug!=="audit_logs").map(f=>({slug:f.slug,label:f.label,labelPlural:f.labelPlural,singularLabel:f.singularLabel,timestamps:f.timestamps,auth:!!f.auth,tenantScoped:!!f.tenantScoped,upload:f.upload?{staticDir:f.upload.staticDir,imageSizes:f.upload.imageSizes,mimeTypes:f.upload.mimeTypes}:void 0,fields:f.fields.map(so)}));return l.json(g)}catch(y){return console.error("[Schema] error:",y),l.json({error:y.message},500)}});let Hd=e.getCollections();for(let l of Hd){let R=function(g,f){let _=[],C=new Set([...Object.keys(g),...Object.keys(f)]);for(let S of C)S==="id"||S==="createdAt"||S==="updatedAt"||JSON.stringify(g[S])!==JSON.stringify(f[S])&&_.push({field:S,oldValue:S in g?g[S]:void 0,newValue:S in f?f[S]:void 0});return _};let y=l.slug;if(y==="users"||y==="audit_logs")continue;let v=`/api/${y}`;w.post(`${v}/dynamic-options/:fieldName`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"read",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=g.req.param("fieldName"),D=await g.req.json(),{data:P,siblingData:j}=D,N=vs(l.fields,E);if(!N)return g.json({error:"Field not found"},404);if(N.type!=="select")return g.json({error:"Field is not a select field"},400);let z=[];return typeof N.options=="function"?z=await N.options({data:P||{},siblingData:j||{}}):Array.isArray(N.options)&&(z=N.options),g.json({options:z})}catch(f){return g.json({error:f.message},500)}}),w.get(v,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"read",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);_&&r.setTenantContext({tenantId:_,userId:f?.id??"",role:f?.role,isSuperAdmin:f?.role==="super_admin"});let E=new URL(g.req.url),D=parseInt(E.searchParams.get("page")||"1"),P=Math.min(parseInt(E.searchParams.get("limit")||"10"),100),j=E.searchParams.get("sort")||void 0,N=parseInt(E.searchParams.get("depth")||"0"),z=E.searchParams.get("select")?.split(",")||void 0,Y=E.searchParams.get("draft"),ue=Y==="true"?!0:Y==="false"?!1:!!f,J={},ye=E.searchParams.get("where");if(ye)try{J=JSON.parse(ye);}catch{return g.json({error:"Invalid JSON in where parameter"},400)}let Je=await r.find({collection:y,where:J,sort:j,limit:P,page:D,depth:N,tenantId:_,select:z,draft:ue});return await chunkAK754S3T_cjs.a(Je.docs,l.fields,r,e,1,N),g.json(chunkZOVH6QT5_cjs.a(Je))}catch(f){return console.error("[API] list error:",f),g.json({error:f.message},500)}}),w.get(`${v}/:id/versions`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"read",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=g.req.param("id");if(!E)return g.json({error:"Missing document ID"},400);let D=new URL(g.req.url),P=D.searchParams.get("compareA"),j=D.searchParams.get("compareB");if(Nc(V,C,`${v}/${E}/versions`,"GET",g.req.raw),P&&j){let[ue,J]=await Promise.all([r.findVersionByID({collection:y,versionId:P,tenantId:_}),r.findVersionByID({collection:y,versionId:j,tenantId:_})]);if(!ue||!J)return g.json({error:"Version not found"},404);let ye=R(ue.data,J.data);return g.json({diffs:ye})}let N=parseInt(D.searchParams.get("page")||"1"),z=Math.min(parseInt(D.searchParams.get("limit")||"10"),100),Y=await r.findVersions({collection:y,documentId:E,page:N,limit:z,tenantId:_});return g.json(Y)}catch(f){return console.error("[API] versions error:",f),g.json({error:f.message},500)}}),w.put(`${v}/:id/draft`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"update",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=g.req.param("id"),D=await g.req.json(),P=Mc(D),j=await r.findByID({collection:y,id:E,tenantId:_,draft:!0});if(!j)return g.json({error:"Document not found"},404);let N;D.delta?N={...j,...D.delta}:N=D.data??qd(D);let z=await r.updateLatestVersion({collection:y,documentId:E,data:N,status:"draft",tenantId:_});return f&&V?.createAuditLog({action:"document_update",userId:f.id,resource:y,resourceId:E,success:!0,metadata:{type:"draft_save"}}),g.json({data:z,message:"Draft saved successfully"})}catch(f){return g.json({error:f.message},500)}}),w.delete(`${v}/:id/draft`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"update",g.req.raw,f,_,C,O,F);return S.allowed?(f&&V?.createAuditLog({action:"document_update",userId:f.id,resource:y,resourceId:g.req.param("id"),success:!0,metadata:{type:"draft_discard"}}),g.json({message:"Draft discarded successfully"})):g.json({error:S.error},S.status||403)}catch(f){return g.json({error:f.message},500)}}),w.get(`${v}/:id`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=new URL(g.req.url),E=S.searchParams.get("draft"),D=S.searchParams.get("kyroToken"),P=!1;if(E==="true"&&D&&s)try{let J=await Pa(D,s,"HS256");J&&J.type==="preview"&&J.collection===l.slug&&(P=!0);}catch(J){console.warn("Invalid preview token",J);}if(!P){let J=await Ie(l,"read",g.req.raw,f,_,C,O,F);if(!J.allowed)return g.json({error:J.error},J.status||403)}let j=g.req.param("id"),N=parseInt(S.searchParams.get("depth")||"0"),z=S.searchParams.get("select")?.split(",")||void 0,Y=E==="true"?!0:E==="false"?!1:!!f,ue=await r.findByID({collection:y,id:j,depth:N,tenantId:_,select:z,draft:Y});return !ue&&l.fields.some(J=>J.name==="slug")&&(ue=await r.findOne({collection:y,where:{slug:j},tenantId:_,draft:Y})),ue?(await chunkAK754S3T_cjs.a([ue],l.fields,r,e,1,N),g.json({data:chunkZOVH6QT5_cjs.a(ue)})):g.json({error:"Document not found"},404)}catch(f){return g.json({error:f.message},500)}}),w.post(`${v}/preview-url`,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await Ie(l,"read",g.req.raw,f,_);if(!C.allowed)return g.json({error:C.error||"Forbidden"},C.status||403);let S=await g.req.json().catch(()=>({})),E="";s&&(E=await Oa({type:"preview",collection:l.slug,id:S.id,exp:Math.floor(Date.now()/1e3)+3600},s,"HS256"));let D="";if(l.admin?.preview){D=await l.admin.preview(S,{req:g.req.raw,token:E});try{let P=new URL(D,"http://localhost");P.searchParams.has("preview")||P.searchParams.set("preview","true"),!P.searchParams.has("kyroToken")&&E&&P.searchParams.set("kyroToken",E),D=D.startsWith("http")?P.toString():`${P.pathname}${P.search}`;}catch{}}else {let P="";try{let N=await r.findOne({collection:"_globals_site-settings",where:{}});N?.siteUrl&&(P=N.siteUrl);}catch{}if(!P)return g.json({error:"No site URL configured in settings, and no custom preview function defined for this collection."},400);P=P.replace(/\/$/,"");let j=S.slug||S.id||"";D=`${P}/${l.slug}/${j}?preview=true&kyroToken=${E}`;}return g.json({url:D})}catch(f){return g.json({error:f.message},500)}}),w.post(v,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"create",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);_&&r.setTenantContext({tenantId:_,userId:f?.id??"",role:f?.role,isSuperAdmin:f?.role==="super_admin"}),Nc(V,C,v,"POST",g.req.raw);let D=await g.req.json();es(D,l.fields),ts(l.fields,D);let P=g.req.raw;if(l.hooks?.beforeValidate)for(let J of l.hooks.beforeValidate){let ye=await J({collection:y,data:D,req:P,user:f,tenantId:_,operation:"create"});ye&&typeof ye=="object"&&!Array.isArray(ye)&&Object.assign(D,ye);}let j=e.getCreateZodSchema(y);try{D=j.parse(D);}catch(J){return g.json({error:`Validation failed: ${fo(J.errors)}`,details:J.errors},400)}l.tenantScoped&&_&&(D.tenantId=_);let N=l.versions?.drafts===!0,z=l.fields.find(J=>J.name==="status"),Y=z?.type==="select"&&Array.isArray(z.options)&&z.options.some(J=>J.value==="published");if(N?D.status="draft":Y&&!D.status&&(D.status="published"),l.hooks?.beforeChange)for(let J of l.hooks.beforeChange){let ye=await J({collection:y,data:D,req:P,user:f,tenantId:_,operation:"create"});ye&&typeof ye=="object"&&!Array.isArray(ye)&&Object.assign(D,ye);}let ue=await r.create({collection:y,data:D,tenantId:_});if(N&&await r.createVersion({collection:y,documentId:ue.id,data:D,status:"draft",createdBy:f?.id,changeDescription:"Created",tenantId:_}),l.hooks?.afterChange)for(let J of l.hooks.afterChange)await J({collection:y,doc:ue,data:D,req:P,user:f,tenantId:_,operation:"create"});return d&&d.trigger(la(y,"create"),{collection:y,operation:"create",data:ue,user:f?{id:f.id,email:f.email,role:f.role}:void 0,tenantId:_}).catch(J=>console.error("[Webhook] Failed to trigger:",J)),f&&V?.createAuditLog({action:"document_create",userId:f.id,resource:y,resourceId:ue.id,success:!0}),g.json({data:ue,message:"Created successfully"},201)}catch(f){return f.name==="ZodError"?g.json({error:`Validation failed: ${fo(f.errors)}`,details:f.errors},400):g.json({error:f.message},500)}}),w.patch(`${v}/:id`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"update",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=g.req.param("id"),D=await g.req.json(),P=Mc(D),j=await r.findByID({collection:y,id:E,tenantId:_,draft:!0});if(!j)return g.json({error:"Document not found"},404);if(P&&j.updatedAt&&P!==j.updatedAt)return g.json(Fd(P,j),409);let N=Object.fromEntries(Object.entries(qd(D)).filter(([Nt,Xe])=>Xe!=="null"&&Xe!==void 0));es(N,l.fields),ts(l.fields,N);let z=g.req.raw;if(l.hooks?.beforeValidate)for(let Nt of l.hooks.beforeValidate){let Xe=await Nt({collection:y,data:N,originalDoc:j,req:z,user:f,tenantId:_,operation:"update"});Xe&&typeof Xe=="object"&&!Array.isArray(Xe)&&Object.assign(N,Xe);}if(N=e.getUpdateZodSchema(y).parse(N),l.hooks?.beforeChange)for(let Nt of l.hooks.beforeChange){let Xe=await Nt({collection:y,data:N,originalDoc:j,req:z,user:f,tenantId:_,operation:"update"});Xe&&typeof Xe=="object"&&!Array.isArray(Xe)&&Object.assign(N,Xe);}let ue=g.req.header("X-Draft")==="true",J=l.versions?.drafts===!0,ye=g.req.query("autosave")==="true",Je;if(J&&ue?await r.createVersion({collection:y,documentId:E,data:N,status:"draft",autosave:ye,createdBy:f?.id,changeDescription:ye?"Autosave":"Draft saved",tenantId:_}):J?(await r.update({collection:y,id:E,data:{...N,status:"published"},tenantId:_}),await r.createVersion({collection:y,documentId:E,data:N,status:"published",createdBy:f?.id,changeDescription:"Published",tenantId:_})):await r.update({collection:y,id:E,data:N,tenantId:_}),Je=await r.findByID({collection:y,id:E,tenantId:_,draft:!0}),l.hooks?.afterChange)for(let Nt of l.hooks.afterChange)await Nt({collection:y,doc:Je,data:N,originalDoc:j,req:z,user:f,tenantId:_,operation:"update"});return d&&!ye&&d.trigger(la(y,"update"),{collection:y,operation:"update",data:Je,previousData:j,user:f?{id:f.id,email:f.email,role:f.role}:void 0,tenantId:_}).catch(Nt=>console.error("[Webhook] Failed to trigger:",Nt)),Nc(V,C,`${v}/${E}`,"PATCH",g.req.raw),f&&V?.createAuditLog({action:"document_update",userId:f.id,resource:y,resourceId:E,success:!0}),g.json({data:Je,message:J?"Draft saved":"Updated successfully"})}catch(f){return f.name==="ZodError"?(console.error(`[PATCH ${v}/:id] Validation failed:`,f.errors),g.json({error:`Validation failed: ${fo(f.errors)}`,details:f.errors},400)):(console.error(`[PATCH ${v}/:id] ERROR:`,f.message,"CAUSE:",f.cause?.message||f.cause,"QUERY:",f.query),g.json({error:f.message},500))}}),w.delete(`${v}/:id`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"delete",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);_&&r.setTenantContext({tenantId:_,userId:f?.id??"",role:f?.role,isSuperAdmin:f?.role==="super_admin"});let E=g.req.param("id"),D=g.req.raw,P=await r.findByID({collection:y,id:E,tenantId:_,draft:!0});if(!P)return g.json({error:"Document not found"},404);if(l.hooks?.beforeDelete)for(let N of l.hooks.beforeDelete)await N({collection:y,doc:P,req:D,user:f,tenantId:_,operation:"delete"});let j=await r.delete({collection:y,id:E,tenantId:_});if(l.hooks?.afterDelete)for(let N of l.hooks.afterDelete)await N({collection:y,doc:j,originalDoc:P,req:D,user:f,tenantId:_,operation:"delete"});return d&&d.trigger(la(y,"delete"),{collection:y,operation:"delete",data:j,previousData:P,user:f?{id:f.id,email:f.email,role:f.role}:void 0,tenantId:_}).catch(N=>console.error("[Webhook] Failed to trigger:",N)),Nc(V,C,`${v}/${E}`,"DELETE",g.req.raw),f&&V?.createAuditLog({action:"document_delete",userId:f.id,resource:y,resourceId:E,success:!0}),g.json({data:j,message:"Deleted successfully"})}catch(f){return console.error(`[DELETE] Error deleting ${y}:`,f),g.json({error:f.message||String(f)},500)}}),w.post(`${v}/:id/duplicate`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"create",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=g.req.param("id"),D=await r.findByID({collection:y,id:E,tenantId:_,draft:!0});if(!D)return g.json({error:"Document not found"},404);let{id:P,createdAt:j,updatedAt:N,...z}=D;Ws(l.fields,z);let Y=Date.now().toString(36);"slug"in z&&typeof z.slug=="string"&&(z.slug=`${z.slug||"document"}-copy-${Y}`),"title"in z&&typeof z.title=="string"?z.title=`${z.title||"Copy"} (Copy)`:"name"in z&&typeof z.name=="string"&&(z.name=`${z.name||"Copy"} (Copy)`);let ue=await r.create({collection:y,data:{...z,status:"draft"},tenantId:_});return g.json({data:ue,message:"Document duplicated successfully"})}catch(f){return console.error("[Duplicate] Error:",f),g.json({error:f.message||String(f)},500)}}),w.post(`${v}/:id/versions/:versionId/restore`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"update",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=g.req.param("id"),D=g.req.param("versionId"),P=await r.findVersionByID({collection:y,versionId:D,tenantId:_});if(!P)return g.json({error:"Version not found"},404);let j=await r.update({collection:y,id:E,data:{...P.data,status:"draft"},tenantId:_});return g.json({data:j,message:"Version restored successfully"})}catch(f){return g.json({error:f.message},500)}}),w.post(`${v}/:id/versions`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"update",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=await g.req.json(),{versionId:D,action:P}=E;if(P==="restore"&&D){let j=await r.findVersionByID({collection:y,versionId:D,tenantId:_});if(!j)return g.json({error:"Version not found"},404);let N=await r.update({collection:y,id:g.req.param("id"),data:{...j.data,status:"draft"},tenantId:_});return g.json({data:N,message:"Version restored successfully"})}return g.json({error:"Invalid action"},400)}catch(f){return g.json({error:f.message},500)}}),w.post(`${v}/:id/publish`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"update",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);_&&r.setTenantContext({tenantId:_,userId:f?.id??"",role:f?.role,isSuperAdmin:f?.role==="super_admin"});let E=g.req.param("id"),D=await g.req.json().catch(()=>({})),P=Mc(D),j=await r.findByID({collection:y,id:E,tenantId:_,draft:!0});if(!j)return g.json({error:"Document not found"},404);if(P&&j.updatedAt&&P!==j.updatedAt)return g.json(Fd(P,j),409);let N={status:"published"},z=j;if(l.versions?.drafts){let ue=await r.findVersions({collection:y,documentId:E,limit:1,sort:"-createdAt",tenantId:_});if(ue.docs.length>0){let J=ue.docs[0];z={...j,...J.data},N={...J.data,...N};}}let Y=await r.update({collection:y,id:E,data:N,tenantId:_});return l.versions?.drafts&&await r.createVersion({collection:y,documentId:E,data:{...z,status:"published"},status:"published",createdBy:f?.id,changeDescription:"Published",tenantId:_}),d&&d.trigger(la(y,"update"),{collection:y,operation:"update",data:Y,user:f?{id:f.id,email:f.email,role:f.role}:void 0,tenantId:_}).catch(ue=>console.error("[Webhook] Failed to trigger:",ue)),g.json({data:Y,message:"Published successfully"})}catch(f){return g.json({error:f.message},500)}}),w.post(`${v}/:id/unpublish`,async g=>{try{let{user:f,tenantId:_,apiKeyContext:C}=await W(g.req.raw,H,i,c),S=await Ie(l,"update",g.req.raw,f,_,C,O,F);if(!S.allowed)return g.json({error:S.error},S.status||403);let E=g.req.param("id");if(!await r.findByID({collection:y,id:E,tenantId:_,draft:!0}))return g.json({error:"Document not found"},404);let P=await r.update({collection:y,id:E,data:{status:"draft"},tenantId:_});return d&&d.trigger(la(y,"update"),{collection:y,operation:"update",data:P,user:f?{id:f.id,email:f.email,role:f.role}:void 0,tenantId:_}).catch(j=>console.error("[Webhook] Failed to trigger:",j)),g.json({data:P,message:"Unpublished successfully"})}catch(f){return g.json({error:f.message},500)}});}for(let l of e.getGlobals()){let y=l.slug,v=`/api/globals/${y}`;w.post(`${v}/dynamic-options/:fieldName`,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await tr(l,"read",g.req.raw,f,_,O);if(!C.allowed)return g.json({error:C.error},C.status||403);let S=g.req.param("fieldName"),E=await g.req.json(),{data:D,siblingData:P}=E,j=vs(l.fields,S);if(!j)return g.json({error:"Field not found"},404);if(j.type!=="select")return g.json({error:"Field is not a select field"},400);let N=[];return typeof j.options=="function"?N=await j.options({data:D||{},siblingData:P||{}}):Array.isArray(j.options)&&(N=j.options),g.json({options:N})}catch(f){return g.json({error:f.message},500)}}),w.get(v,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=new URL(g.req.url),S=C.searchParams.get("kyroToken"),E=C.searchParams.get("draft"),D=!1;if(E==="true"&&S&&s)try{let Y=await Pa(S,s,"HS256");Y&&Y.type==="preview"&&Y.collection===`_globals_${l.slug}`&&(D=!0);}catch(Y){console.warn("Invalid preview token",Y);}if(!D){let Y=await tr(l,"read",g.req.raw,f,_,O);if(!Y.allowed)return g.json({error:Y.error},Y.status||403)}let P=E==="true"?!0:E==="false"?!1:!!f,j=parseInt(C.searchParams.get("depth")||"0"),z=(await r.find({collection:`_globals_${y}`,where:{},tenantId:_,draft:P,depth:j,limit:1})).docs[0];if(z&&j>0&&await chunkAK754S3T_cjs.a([z],l.fields,r,e,1,j),y==="storage-settings"&&(typeof globalThis.STORAGE_BUCKET<"u"||typeof g.env?.STORAGE_BUCKET<"u")&&(z?z.provider||(z.provider="cloudflare_r2"):z={id:y,provider:"cloudflare_r2"}),y==="system"){let Y=lv__default.default.randomBytes(32).toString("hex");z?z.appSecret||(await r.update({collection:`_globals_${y}`,id:y,data:{appSecret:Y},tenantId:_}),z.appSecret=Y):z=await r.create({collection:`_globals_${y}`,data:{id:y,appSecret:Y},tenantId:_});}return g.json({data:z||{}})}catch(f){return g.json({error:f.message},500)}});let R=async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await tr(l,"update",g.req.raw,f,_,O);if(!C.allowed)return g.json({error:C.error},C.status||403);let S=new URL(g.req.url),E=parseInt(S.searchParams.get("depth")||"0"),D=await g.req.json(),P=Mc(D),j=qd(D),N=Object.fromEntries(Object.entries(j).filter(([It,js])=>js!==null&&js!=="null"&&js!==void 0));es(N,l.fields),ts(l.fields,N);let z=e.getUpdateZodSchema(y),Y;try{Y=z.parse(N);}catch(It){return g.json({error:`Validation failed: ${fo(It.errors)}`,details:It.errors},400)}let ue=new Set(["id","createdAt","updatedAt","status","baseUpdatedAt","_baseUpdatedAt"]),J=Object.fromEntries(Object.entries(Y).filter(([It])=>!ue.has(It))),ye=`_globals_${y}`,Je=await r.findOne({collection:ye,where:{},tenantId:_,draft:!0});if(Je&&P&&Je.updatedAt&&P!==Je.updatedAt)return g.json(Fd(P,Je),409);let Nt=g.req.header("X-Draft")==="true",Xe=l.versions?.drafts===!0,Xr=g.req.query("autosave")==="true",St;if(Xe&&Nt)await r.createVersion({collection:ye,documentId:y,data:J,status:"draft",autosave:Xr,createdBy:f?.id,changeDescription:Xr?"Autosave":"Manual save",tenantId:_}),Je?St=Je:St=await r.create({collection:ye,data:{...J,id:y,status:"draft"},tenantId:_});else if(Xe&&!Nt){let It="published";Je?St=await r.update({collection:ye,id:y,data:{...J,status:It},tenantId:_}):St=await r.create({collection:ye,data:{...J,id:y,status:It},tenantId:_}),await r.createVersion({collection:ye,documentId:y,data:J,status:It,autosave:!1,createdBy:f?.id,changeDescription:"Published",tenantId:_});}else Je?St=await r.update({collection:ye,id:y,data:J,tenantId:_}):St=await r.create({collection:ye,data:{...J,id:y},tenantId:_});if(y==="storage-settings"&&(Bt=null,$r=null),y==="email-settings"){let It=await chunkP7XYIKL6_cjs.k.fromConfig(r);Re.email=It||void 0;}return y==="system"&&await gm(),f&&V?.createAuditLog({action:"settings_change",userId:f.id,resource:`global:${y}`,resourceId:y,success:!0}),St&&E>0&&await chunkAK754S3T_cjs.a([St],l.fields,r,e,1,E),g.json({data:St,message:"Updated successfully"})}catch(f){return console.error(`[API] Save global "${y}" failed:`,f),g.json({error:f.message||"Save failed",stack:process.env.NODE_ENV==="development"?f.stack:void 0},500)}};w.post(v,R),w.patch(v,R),w.post(`${v}/preview-url`,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await tr(l,"read",g.req.raw,f,_);if(!C.allowed)return g.json({error:C.error||"Forbidden"},C.status||403);let S=await g.req.json().catch(()=>({})),E="";s&&(E=await Oa({type:"preview",collection:`_globals_${l.slug}`,exp:Math.floor(Date.now()/1e3)+3600},s,"HS256"));let D="";if(l.admin?.preview)D=await l.admin.preview(S,{req:g.req.raw,token:E});else {let P="";try{let j=await r.findOne({collection:"_globals_site-settings",where:{}});j?.siteUrl&&(P=j.siteUrl);}catch{}if(!P)return g.json({error:"No site URL configured in settings, and no custom preview function defined."},400);P=P.replace(/\/$/,""),D=`${P}/?preview=true&kyroToken=${E}`;}return g.json({url:D})}catch(f){return g.json({error:f.message},500)}}),w.post(`${v}/publish`,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await tr(l,"update",g.req.raw,f,_,O);if(!C.allowed)return g.json({error:C.error},403);let S=`_globals_${y}`,E=await r.findOne({collection:S,where:{},tenantId:_,draft:!0});if(!E)return g.json({error:"Global not found"},404);let D={status:"published"},P=E;if(l.versions?.drafts){let N=await r.findVersions({collection:S,documentId:y,limit:1,sort:"-createdAt",tenantId:_});N.docs.length>0&&(P={...E,...N.docs[0].data},D={...N.docs[0].data,...D});}let j=await r.update({collection:S,id:y,data:D,tenantId:_});return l.versions?.drafts&&await r.createVersion({collection:S,documentId:y,data:{...P,status:"published"},status:"published",createdBy:f?.id,changeDescription:"Published",tenantId:_}),g.json({data:j,message:"Published successfully"})}catch(f){return g.json({error:f.message},500)}}),w.post(`${v}/unpublish`,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await tr(l,"update",g.req.raw,f,_,O);if(!C.allowed)return g.json({error:C.error},403);let S=await r.update({collection:`_globals_${y}`,id:y,data:{status:"draft"},tenantId:_});return g.json({data:S,message:"Unpublished successfully"})}catch(f){return g.json({error:f.message},500)}}),w.get(`${v}/versions`,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await tr(l,"read",g.req.raw,f,_,O);if(!C.allowed)return g.json({error:C.error},403);let S=parseInt(g.req.query("limit")||"10"),E=parseInt(g.req.query("page")||"1"),D=await r.findVersions({collection:`_globals_${y}`,documentId:y,limit:S,page:E,tenantId:_});return g.json(D)}catch(f){return g.json({error:f.message},500)}}),w.get(`${v}/versions/:versionId`,async g=>{try{let f=g.req.param("versionId"),{user:_,tenantId:C}=await W(g.req.raw,H,i,c),S=await tr(l,"read",g.req.raw,_,C,O);if(!S.allowed)return g.json({error:S.error},403);let E=await r.findVersionByID({collection:`_globals_${y}`,versionId:f,tenantId:C});return E?g.json({data:E}):g.json({error:"Version not found"},404)}catch(f){return g.json({error:f.message},500)}}),w.post(`${v}/versions/:versionId/restore`,async g=>{try{let f=g.req.param("versionId"),{user:_,tenantId:C}=await W(g.req.raw,H,i,c),S=await tr(l,"update",g.req.raw,_,C,O);if(!S.allowed)return g.json({error:S.error},403);let E=`_globals_${y}`,D=await r.findVersionByID({collection:E,versionId:f,tenantId:C});if(!D)return g.json({error:"Version not found"},404);let P=await r.update({collection:E,id:y,data:{...D.data,status:"draft"},tenantId:C});return g.json({data:P,message:"Version restored successfully"})}catch(f){return g.json({error:f.message},500)}}),y==="email-settings"&&w.post(`${v}/test`,async g=>{try{let{user:f,tenantId:_}=await W(g.req.raw,H,i,c),C=await tr(l,"update",g.req.raw,f,_,O);if(!C.allowed)return g.json({error:C.error},C.status||403);let S=await g.req.json(),E={provider:S.provider,from:S.fromEmail||S.from,fromName:S.fromName,replyTo:S.replyTo,smtp:S.smtp?{host:S.smtp.host,port:S.smtp.port,secure:S.smtp.secure,auth:{user:S.smtp.username||S.smtp.user,pass:S.smtp.password||S.smtp.pass}}:void 0,resend:S.resend,sendgrid:S.sendgrid,mailgun:S.mailgun,ses:S.ses},D=new chunkP7XYIKL6_cjs.k(E),P=S.email||S.testEmail||S.testEmailSection&&S.testEmailSection.testEmail;if(!P)return g.json({error:"No test recipient email provided"},400);let j=S.provider?S.provider.charAt(0).toUpperCase()+S.provider.slice(1):"SMTP",N=S.fromName?`${S.fromName} <${S.fromEmail||S.from||"default"}>`:S.fromEmail||S.from||"Configured Sender",z=new Date().toUTCString();return await D.send({to:P,subject:"Kyro CMS \u2014 Email Connection Test",html:`<!DOCTYPE html>
125
125
  <html lang="en">
126
126
  <head>
127
127
  <meta charset="UTF-8">