@heyo-sh/heyo-cms 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/astro.d.ts +12 -5
- package/dist/adapters/astro.d.ts.map +1 -1
- package/dist/adapters/astro.js +1 -1
- package/dist/adapters/deliver.d.ts +26 -0
- package/dist/adapters/deliver.d.ts.map +1 -0
- package/dist/adapters/next.d.ts +26 -12
- package/dist/adapters/next.d.ts.map +1 -1
- package/dist/adapters/next.js +1 -1
- package/dist/adapters/nuxt.d.ts +10 -6
- package/dist/adapters/nuxt.d.ts.map +1 -1
- package/dist/adapters/nuxt.js +1 -1
- package/dist/adapters/react-router.d.ts +12 -5
- package/dist/adapters/react-router.d.ts.map +1 -1
- package/dist/adapters/react-router.js +1 -1
- package/dist/adapters/sveltekit.d.ts +9 -5
- package/dist/adapters/sveltekit.d.ts.map +1 -1
- package/dist/adapters/sveltekit.js +1 -1
- package/dist/ai.js +1 -1
- package/dist/auth.js +1 -1
- package/dist/cli.js +2 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/types.d.ts +24 -1
- package/dist/client/types.d.ts.map +1 -1
- package/dist/client.js +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/content.js +1 -1
- package/dist/db/d1.js +1 -1
- package/dist/db/mongodb.js +2 -2
- package/dist/db/postgres.js +1 -1
- package/dist/db/sql/dialect.d.ts +2 -0
- package/dist/db/sql/dialect.d.ts.map +1 -1
- package/dist/db/sqlite.d.ts +13 -2
- package/dist/db/sqlite.d.ts.map +1 -1
- package/dist/db/sqlite.js +1 -1
- package/dist/editor/builtin.d.ts.map +1 -1
- package/dist/editor/serialize.d.ts.map +1 -1
- package/dist/editor.d.ts +1 -1
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +1 -1
- package/dist/engine/engine.d.ts +19 -0
- package/dist/engine/engine.d.ts.map +1 -1
- package/dist/engine/slugs.d.ts +124 -0
- package/dist/engine/slugs.d.ts.map +1 -0
- package/dist/fields/builtin.d.ts +42 -15
- package/dist/fields/builtin.d.ts.map +1 -1
- package/dist/fields.d.ts +1 -0
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +1 -1
- package/dist/http/handler.d.ts.map +1 -1
- package/dist/http/rich-text.d.ts +12 -1
- package/dist/http/rich-text.d.ts.map +1 -1
- package/dist/http/routes/documents.d.ts.map +1 -1
- package/dist/http/routes/media.d.ts +30 -0
- package/dist/http/routes/media.d.ts.map +1 -1
- package/dist/http.js +1 -1
- package/dist/index-2ddk43me.js +2 -0
- package/dist/index-2prbs05k.js +2 -0
- package/dist/index-385ggnge.js +2 -0
- package/dist/{index-7k091gpe.js → index-466cwb0b.js} +2 -2
- package/dist/{index-b2ecggck.js → index-4qrep5f0.js} +6 -6
- package/dist/{index-k8wbg1dw.js → index-67e458ws.js} +2 -2
- package/dist/index-6m1kjq9g.js +2 -0
- package/dist/index-6w10rch0.js +3 -0
- package/dist/index-761dec5z.js +2 -0
- package/dist/{index-2kb5nbxx.js → index-8nzmqy0f.js} +2 -2
- package/dist/{index-vq2978e7.js → index-8x2em6c8.js} +8 -8
- package/dist/index-91fa1gzf.js +2 -0
- package/dist/index-a8jcwqsf.js +2 -0
- package/dist/index-abfzb1ve.js +2 -0
- package/dist/index-cv0hpz3d.js +2 -0
- package/dist/index-g041kfa5.js +18 -0
- package/dist/index-hbx67b20.js +7 -0
- package/dist/index-hpast878.js +40 -0
- package/dist/index-kc1j3h6z.js +2 -0
- package/dist/index-p2cqsmvw.js +2 -0
- package/dist/index-rg9tpg3p.js +5 -0
- package/dist/{index-cbwwtcm4.js → index-rw0hze6x.js} +2 -2
- package/dist/index-s9x07zb3.js +2 -0
- package/dist/index-sgdnp83t.js +2 -0
- package/dist/{index-34s342fz.js → index-szaq03qq.js} +2 -2
- package/dist/{index-9x1z3b85.js → index-vkwzdfte.js} +4 -4
- package/dist/{index-gpwcmmvr.js → index-vzhxn50e.js} +2 -2
- package/dist/index-y8kzzn94.js +2 -0
- package/dist/{index-7a231xfp.js → index-ypcmns0v.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/jobs.js +1 -1
- package/dist/media/cloudflare.d.ts +58 -0
- package/dist/media/cloudflare.d.ts.map +1 -0
- package/dist/media/document.d.ts +7 -6
- package/dist/media/document.d.ts.map +1 -1
- package/dist/media/gc.d.ts.map +1 -1
- package/dist/media/pipeline.d.ts +19 -0
- package/dist/media/pipeline.d.ts.map +1 -1
- package/dist/media/service.d.ts.map +1 -1
- package/dist/media/urls.d.ts +77 -0
- package/dist/media/urls.d.ts.map +1 -0
- package/dist/media/usages.d.ts +9 -1
- package/dist/media/usages.d.ts.map +1 -1
- package/dist/media/variants.d.ts +11 -0
- package/dist/media/variants.d.ts.map +1 -1
- package/dist/migrations.js +1 -1
- package/dist/plugins/indexnow.d.ts +82 -0
- package/dist/plugins/indexnow.d.ts.map +1 -0
- package/dist/plugins.d.ts +9 -0
- package/dist/plugins.d.ts.map +1 -0
- package/dist/plugins.js +1 -0
- package/dist/query.js +1 -1
- package/dist/{run-3r72dwhs.js → run-bjge3v8e.js} +4 -4
- package/dist/schema/snapshot.d.ts +2 -0
- package/dist/schema/snapshot.d.ts.map +1 -1
- package/dist/schema/system.d.ts +9 -0
- package/dist/schema/system.d.ts.map +1 -1
- package/dist/schema.js +1 -1
- package/dist/slugify.d.ts +31 -0
- package/dist/slugify.d.ts.map +1 -0
- package/dist/telemetry.js +1 -1
- package/dist/types/api.d.ts +56 -0
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/config.d.ts +15 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/editor.d.ts +26 -0
- package/dist/types/editor.d.ts.map +1 -1
- package/dist/types/media.d.ts +97 -0
- package/dist/types/media.d.ts.map +1 -1
- package/dist/types/plugin.d.ts +23 -1
- package/dist/types/plugin.d.ts.map +1 -1
- package/dist/uploads.d.ts +1 -0
- package/dist/uploads.d.ts.map +1 -1
- package/dist/uploads.js +4 -4
- package/dist/webhooks.js +1 -1
- package/package.json +9 -5
- package/dist/index-2757kej5.js +0 -2
- package/dist/index-2z1qe5mw.js +0 -2
- package/dist/index-5ngtc7gy.js +0 -2
- package/dist/index-9zqnf6gx.js +0 -23
- package/dist/index-hq05mc1n.js +0 -3
- package/dist/index-hy1x46nf.js +0 -2
- package/dist/index-kbsgt44t.js +0 -2
- package/dist/index-m82a0shw.js +0 -2
- package/dist/index-md79xr6h.js +0 -5
- package/dist/index-nvgwyykk.js +0 -40
- package/dist/index-ty698y02.js +0 -2
- package/dist/index-vxw0a03g.js +0 -2
- package/dist/index-wj8y1xcj.js +0 -2
- package/dist/index-y5mwknr9.js +0 -2
- package/dist/index-ymq6jsar.js +0 -2
package/dist/index-nvgwyykk.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import{s,k,Fn,t}from"./index-vxw0a03g.js";import{P}from"./index-2z1qe5mw.js";import{de,ue}from"./index-9zqnf6gx.js";import{ce,C,_}from"./index-vq2978e7.js";import{Qn,se}from"./index-7a231xfp.js";import{d}from"./index-9g2n7xa6.js";import{g}from"./index-ymq6jsar.js";import{fe}from"./index-5ngtc7gy.js";import{b,ee}from"./index-cbwwtcm4.js";import{e,n}from"./index-x72d1hzh.js";import{z as Tt}from"zod";function Fe(c){if(!c)throw e.unauthorized("This endpoint needs a session or an API key.");return c}function m(c,u,w){let p=Fe(u);if(!c.rbac)return p;if(!P(p,w))throw e.forbidden(`This action needs "${w}".`);return p}function Je(c){let u=Fe(c);if(u.source!=="session")throw e.forbidden("This endpoint needs a signed-in user; an API key cannot issue credentials.");return u}function y(c){return c.headers.get("x-heyo-cms-client")==="admin"?"admin":"rest"}var wt=new Set(["where","sort","limit","offset","cursor","count","depth","locale","fallbackLocale","includeTrashed","permanent","refresh","force","richText"]),vt={id:"id",createdAt:"created_at",created_at:"created_at",updatedAt:"updated_at",updated_at:"updated_at",updatedBy:"updated_by",updated_by:"updated_by",deletedAt:"deleted_at",deleted_at:"deleted_at",purgeAfter:"purge_after",purge_after:"purge_after",scheduledAt:"scheduled_at",scheduled_at:"scheduled_at"},Rt=new Set(["created_at","updated_at","deleted_at","purge_after","scheduled_at"]),he=new Set(["eq","ne","gt","gte","lt","lte","in","nin","like","ilike","contains","exists"]),Te=100;function E(c,u){let w=c.get("locale"),p=c.get("fallbackLocale"),j=R(c.get("depth"),"depth",0,10);return{actor:u.actor,...u.source===void 0?{}:{source:u.source},...w===null?{}:{locale:w},...p===null?{}:{fallbackLocale:p==="false"?!1:p},...j===void 0?{}:{depth:j},...H(c.get("includeTrashed"),"includeTrashed")===!0?{includeTrashed:!0}:{}}}function vn(c,u,w){let p=E(c,w),j=p.locale??null,A=Kn(c,u,j),S=Yn(c.get("sort"),u,j),I=R(c.get("limit"),"limit",1,500),T=R(c.get("offset"),"offset",0,Number.MAX_SAFE_INTEGER),q=c.get("cursor");return{...p,...A===void 0?{}:{where:A},...S===void 0?{}:{orderBy:S},...I===void 0?{}:{limit:I},...T===void 0?{}:{offset:T},...q===null?{}:{cursor:q},...H(c.get("count"),"count")===!0?{count:!0}:{}}}function Kn(c,u,w){let p=[],j=c.get("where");if(j!==null&&j.trim().length>0)p.push(kt(j,u,w));for(let[A,S]of c.entries()){if(wt.has(A))continue;let I=/^([A-Za-z_][A-Za-z0-9_.]*)(?:\[([a-z]+)\])?$/.exec(A);if(!I)throw e.validation(`"${A}" is not a filter; see the OpenAPI document for the query syntax.`);let[,T="",q="eq"]=I;if(!he.has(q))throw e.validation(`"${q}" is not a comparison; use one of ${[...he].join(", ")}.`);let O=ye(T,u,w),J=q;p.push({kind:"compare",path:O.path,operator:J,value:J==="in"||J==="nin"?S.split(",").map((x)=>qe(x,O)):qe(S,O)})}if(p.length===0)return;return p.length===1?p[0]:s(...p)}function kt(c,u,w){let p;try{p=JSON.parse(c)}catch{throw e.validation('"where" has to be a JSON filter.')}let j=0,A=(S)=>{if(j+=1,j>Te)throw e.validation(`"where" has more than ${Te} conditions.`);if(typeof S!=="object"||S===null||Array.isArray(S))throw e.validation('every node of "where" has to be an object.');let I=S;switch(I.kind){case"and":case"or":{let T=I.conditions;if(!Array.isArray(T))throw e.validation(`"${I.kind}" needs a "conditions" array.`);let q=T.map(A);return I.kind==="and"?s(...q):k(...q)}case"not":return Fn(A(I.condition));case"compare":{let{path:T,operator:q}=I;if(typeof T!=="string")throw e.validation('"compare" needs a "path".');if(typeof q!=="string"||!he.has(q))throw e.validation(`"${String(q)}" is not a comparison.`);let O=ye(T,u,w);return{kind:"compare",path:O.path,operator:q,value:Ce(I.value,O)}}default:throw e.validation(`"${String(I.kind)}" is not a filter node.`)}};return A(p)}function Yn(c,u,w){if(c===null||c.trim().length===0)return;let p=[];for(let j of c.split(",")){let A=j.trim();if(A.length===0)continue;let S=A.startsWith("-"),I=S?A.slice(1):A;p.push({path:ye(I,u,w).path,direction:S?"desc":"asc"})}return p.length===0?void 0:p}function ye(c,u,w){let[p="",...j]=c.split("."),A=vt[p];if(A!==void 0&&j.length===0)return{path:A,type:Rt.has(A)?"timestamp":"text"};let S=u.fields[p];if(!S)throw e.validation(`"${c}" is not a field of ${u.name}, and not a system column.`);if(j.length>2)throw e.validation(`"${c}" is nested too deeply to filter.`);let I=S.localized&&j.length===0?[w??""]:j;return{path:[p,...I.filter((q)=>q.length>0)].join("."),type:jt(S.column.type)}}function jt(c){switch(c){case"integer":case"bigint":case"real":return"number";case"boolean":return"boolean";case"timestamp":return"timestamp";case"json":return"json";default:return"text"}}function qe(c,u){if(c==="null")return null;switch(u.type){case"number":{let w=Number(c);if(!Number.isFinite(w))throw e.validation(`"${c}" is not a number for ${u.path}.`);return w}case"boolean":{if(c==="true")return!0;if(c==="false")return!1;throw e.validation(`"${c}" is not a boolean for ${u.path}.`)}case"timestamp":return Se(c,u.path);default:return c}}function Ce(c,u){if(Array.isArray(c))return c.map((w)=>Ce(w,u));if(u.type==="timestamp"&&typeof c==="string")return Se(c,u.path);if(c===null||typeof c==="string"||typeof c==="number"||typeof c==="boolean")return c;throw e.validation(`${u.path} cannot be compared to an object.`)}function Se(c,u){let w=new Date(c);if(Number.isNaN(w.getTime()))throw e.validation(`"${c}" is not a date for ${u}.`);return w}function R(c,u,w,p){if(c===null||c.trim().length===0)return;let j=Number(c);if(!Number.isInteger(j)||j<w||j>p)throw e.validation(`"${u}" has to be an integer between ${w} and ${p}.`);return j}function H(c,u){if(c===null)return;if(c===""||c==="true"||c==="1")return!0;if(c==="false"||c==="0")return!1;throw e.validation(`"${u}" has to be true or false.`)}function re(c){if(c===null||c==="")return;if(c==="html"||c==="markdown"||c==="text")return c;throw e.validation(`"${c}" is not a rich-text format; use html, markdown or text.`)}function ne(c,u){for(let[w,p]of Object.entries(u.collection.fields)){if(p.type!=="richText")continue;if(!(w in c))continue;let j=c[w];if(j===null||typeof j!=="object")continue;c[w]=ue(j,{format:u.format,mediaUrl:u.mediaUrl})}return c}function $e(c,u){for(let w of c)ne(w,u)}function ge(c){return(u)=>`${c}/media/${u}/original`}var At="application/json; charset=utf-8";function i(c,u=200,w){return new Response(JSON.stringify(c??null),{status:u,headers:{"content-type":At,...w}})}function An(c,u=200){return new Response(c,{status:u,headers:{"content-type":"text/plain; charset=utf-8"}})}function G(c){return new Response(null,{status:204,...c?{headers:c}:{}})}function B(){return G({"x-heyo-cms-stopped":"before-hook"})}function Gt(c){if(c instanceof e){let u={error:{message:c.message,code:c.code,status:c.status}};if(c.details!==void 0)u.error.details=c.details;return i(u,c.status)}return console.error("[heyo-cms] unhandled error while serving a request",c),i({error:{message:"Internal server error.",code:"internal_error",status:500}},500)}async function Kt(c){let u=await c.text();if(u.trim().length===0)return{};try{return JSON.parse(u)}catch{throw new e("The request body is not valid JSON.",{status:400,code:"invalid_body"})}}async function f(c){let u=await Kt(c);if(typeof u!=="object"||u===null||Array.isArray(u))throw new e("The request body has to be a JSON object.",{status:400,code:"invalid_body"});return u}function Oe(c,u="data"){let w=c[u];if(w===void 0)throw e.validation(`The request body needs a "${u}" object.`);if(typeof w!=="object"||w===null||Array.isArray(w))throw e.validation(`"${u}" has to be a JSON object.`);return w}function v(c,u){let w=c[u];if(typeof w!=="string"||w.trim().length===0)throw e.validation(`"${u}" is required.`);return w}function F(c,u){let w=c[u];if(w===void 0||w===null)return;if(typeof w!=="string")throw e.validation(`"${u}" has to be a string.`);return w}function ve(c,u){let w=c[u];if(w===void 0||w===null)return;if(!(Array.isArray(w)&&w.every((j)=>typeof j==="string")))throw e.validation(`"${u}" has to be an array of strings.`);return w}function o(c){return{$ref:`#/components/schemas/${c}`}}function l(c,u){return{name:c,in:"path",required:!0,description:u,schema:{type:"string"}}}function a(c,u,w,p={}){return{name:c,in:"query",required:!1,description:w,schema:{type:u,...p}}}var K=[a("locale","string","Language to resolve the document in. Defaults to i18n.defaultLocale."),a("fallbackLocale","string",'Where missing values come from for this call; "false" turns substitution off. Defaults to i18n.defaultLocale.')],oe=a("depth","integer","Relation levels to resolve. Each level is one batched query.",{minimum:0,maximum:10});function xn(c){return[...K,oe,a("where","string",`JSON filter AST over ${c}, as produced by the query helpers.`),a("sort","string",'Comma-separated fields, "-" for descending. Defaults to -updatedAt.'),a("limit","integer","Page size. Defaults to 25, capped at 500.",{minimum:1,maximum:500}),a("offset","integer","Rows to skip. Prefer `cursor`."),a("cursor","string","Keyset cursor from the previous page."),a("count","boolean","Runs a second COUNT query and fills totalDocs."),a("includeTrashed","boolean","Includes soft-deleted documents."),{name:"<field>",in:"query",required:!1,description:"Shorthand filter: ?status=draft, ?views[gte]=10, ?tags[in]=news,guide. Any field of the collection or system column (id, createdAt, updatedAt, deletedAt, scheduledAt).",schema:{type:"string"}}]}function h(c,u=!0){return{required:u,content:{"application/json":{schema:c}}}}function r(c,u){return{description:u,content:{"application/json":{schema:c}}}}function M(c,u,w=200){return{[String(w)]:r(c,u),"204":{description:"A `before` hook stopped the operation (x-heyo-cms-stopped)."},"403":r(o("Error"),"Access control refused the operation."),"409":r(o("Error"),"`revision_conflict`: the document changed since the revision the caller sent in `If-Match`."),"422":r(o("Error"),"Validation failed.")}}function yt(c,u){return{"200":r(c,u),"404":r(o("Error"),"No such document.")}}var be=a("richText","string","Renders rich-text fields as `html`, `markdown` or `text` instead of the ProseMirror document. Images resolve through the media id.",{enum:["html","markdown","text"]}),Ie={name:"If-Match",in:"header",required:!1,description:"The `revision` the caller read. The write answers `409` if the document has changed since.",schema:{type:"integer"}};function Ee(c,u){let p=c.headers.get("if-match")??u.revision??u.expectedRevision;if(p===void 0||p===null||p===""||p==="*")return;let j=Number(String(p).replace(/^W\/|"/g,""));if(!Number.isInteger(j)||j<1)throw e.validation(`If-Match / revision has to be a positive integer, received ${String(p)}.`);return j}function xe(c){let{_config:u,api:w}=c,p=[],j=ge(u.basePath);for(let A of Object.values(u.collections)){let S=A.name,I=`/${A.slug}`,T=[A.slug],q=w[S];if(!q)continue;p.push({method:"GET",path:I,source:"core",handler:async(O)=>{let J=await q.find(vn(O.query,A,{actor:O.actor,source:y(O.request)})),x=re(O.query.get("richText"));if(x)$e(J.docs,{collection:A,format:x,mediaUrl:j});return i(J)},openapi:{summary:`List ${A.label}`,tags:T,parameters:[...xn(A.slug),be],responses:{"200":r({type:"object",properties:{docs:{type:"array",items:o(N(A))},limit:{type:"integer"},totalDocs:{type:["integer","null"]},hasNextPage:{type:"boolean"},cursor:{type:["string","null"]}}},"One page of documents.")}}},{method:"POST",path:I,source:"core",handler:async(O)=>{let J=await f(O.request),x=await q.create({...E(O.query,{actor:O.actor,source:y(O.request)}),data:Oe(J)});return x===null?B():i(x,201)},openapi:{summary:`Create a ${A.label}`,tags:T,parameters:K,requestBody:h({type:"object",required:["data"],properties:{data:o(Q(A))}}),responses:M(o(N(A)),"The created document.",201)}},{method:"GET",path:`${I}/:id`,source:"core",handler:async(O)=>{let J=await q.findById(Y(O.params.id),E(O.query,{actor:O.actor,source:y(O.request)}));if(!J)throw e.notFound(`No ${S} with id "${O.params.id}"`);let x=re(O.query.get("richText"));if(x)ne(J,{collection:A,format:x,mediaUrl:j});return i(J)},openapi:{summary:`Read one ${A.label}`,tags:T,parameters:[l("id","Document id."),...K,oe,a("includeTrashed","boolean","Allows reading a document that is in the trash."),be],responses:yt(o(N(A)),"The document.")}},{method:"PATCH",path:`${I}/:id`,source:"core",handler:async(O)=>{let J=await f(O.request),x=Ee(O.request,J),D=await q.update({...E(O.query,{actor:O.actor,source:y(O.request)}),id:Y(O.params.id),data:Oe(J),...x===void 0?{}:{expectedRevision:x}});return D===null?B():i(D)},openapi:{summary:`Update a ${A.label}`,description:"A patch: fields that are absent are left alone. A field the actor may not write is refused, never silently dropped.\n\nSend `If-Match` (or `revision` in the body) with the revision you read to make the write conditional: `409 revision_conflict` instead of overwriting somebody else's save.",tags:T,parameters:[l("id","Document id."),Ie,...K],requestBody:h({type:"object",required:["data"],properties:{data:o(Q(A)),revision:{type:"integer",description:"Same as `If-Match`."}}}),responses:M(o(N(A)),"The document as it now stands.")}},{method:"DELETE",path:`${I}/:id`,source:"core",handler:async(O)=>{let J=H(O.query.get("permanent"),"permanent")===!0,x={...E(O.query,{actor:O.actor,source:y(O.request)}),id:Y(O.params.id)},D=J?await q.purge(x):await q.delete(x);return D===null?B():i(D)},openapi:{summary:`Delete a ${A.label}`,description:u.trash.enabled?"Moves the document to the trash. `?permanent=true` removes the row instead, which needs the purge permission.":"Removes the row; this deployment has no trash.",tags:T,parameters:[l("id","Document id."),a("permanent","boolean","Skips the trash and removes the row.")],responses:M(o(N(A)),"The document as it was when it was removed.")}},{method:"POST",path:`${I}/:id/restore`,source:"core",handler:async(O)=>{let J=await q.restore({...E(O.query,{actor:O.actor,source:y(O.request)}),id:Y(O.params.id)});return J===null?B():i(J)},openapi:{summary:`Restore a ${A.label} from the trash`,tags:T,parameters:[l("id","Document id."),...K],responses:{...M(o(N(A)),"The restored document."),"409":r(o("Error"),"The document is not in the trash.")}}},{method:"POST",path:`${I}/:id/schedule`,source:"core",handler:async(O)=>{let J=await f(O.request),x=await q.schedule({...E(O.query,{actor:O.actor,source:y(O.request)}),id:Y(O.params.id),at:v(J,"at"),data:Oe(J)});return x===null?B():i(x)},openapi:{summary:`Schedule a change to a ${A.label}`,description:"A patch and a time. Checked now — access, field access, validation — and applied later as an ordinary update, so publishing on Friday is refused on Tuesday if the actor may not write the field.",tags:T,parameters:[l("id","Document id."),...K],requestBody:h({type:"object",required:["at","data"],properties:{at:{type:"string",format:"date-time"},data:o(Q(A))}}),responses:M(o(N(A)),"The document carrying the pending change.")}},{method:"DELETE",path:`${I}/:id/schedule`,source:"core",handler:async(O)=>{let J=await q.unschedule({...E(O.query,{actor:O.actor,source:y(O.request)}),id:Y(O.params.id)});return J===null?B():i(J)},openapi:{summary:`Cancel the scheduled change on a ${A.label}`,tags:T,parameters:[l("id","Document id.")],responses:{...M(o(N(A)),"The document."),"409":r(o("Error"),"Nothing was scheduled.")}}})}return p}function De(c){let{_config:u,globals:w}=c,p=[],j=ge(u.basePath);for(let A of Object.values(u.globals)){let S=w[A.name];if(!S)continue;let I=`/globals/${A.slug}`,T=["globals"];p.push({method:"GET",path:I,source:"core",handler:async(q)=>{let O=await S.get(E(q.query,{actor:q.actor,source:y(q.request)})),J=re(q.query.get("richText"));if(J)ne(O,{collection:A,format:J,mediaUrl:j});return i(O)},openapi:{summary:`Read ${A.label}`,description:"Never 404s and never writes: a global nobody has saved reads as its declared defaults with createdAt null.",tags:T,parameters:[...K,oe,be],responses:{"200":r(o(N(A)),"The singleton.")}}},{method:"PATCH",path:I,source:"core",handler:async(q)=>{let O=await f(q.request),J=Ee(q.request,O),x=await S.update({...E(q.query,{actor:q.actor,source:y(q.request)}),data:Oe(O),...J===void 0?{}:{expectedRevision:J}});return x===null?B():i(x)},openapi:{summary:`Update ${A.label}`,description:"Send `If-Match` (or `revision` in the body) with the revision you read to make the write conditional.",tags:T,parameters:[Ie,...K],requestBody:h({type:"object",required:["data"],properties:{data:o(Q(A)),revision:{type:"integer",description:"Same as `If-Match`."}}}),responses:M(o(N(A)),"The singleton.")}},{method:"POST",path:`${I}/schedule`,source:"core",handler:async(q)=>{let O=await f(q.request),J=await S.schedule({...E(q.query,{actor:q.actor,source:y(q.request)}),at:v(O,"at"),data:Oe(O)});return J===null?B():i(J)},openapi:{summary:`Schedule a change to ${A.label}`,tags:T,requestBody:h({type:"object",required:["at","data"],properties:{at:{type:"string",format:"date-time"},data:o(Q(A))}}),responses:M(o(N(A)),"The singleton.")}},{method:"DELETE",path:`${I}/schedule`,source:"core",handler:async(q)=>{let O=await S.unschedule(E(q.query,{actor:q.actor,source:y(q.request)}));return O===null?B():i(O)},openapi:{summary:`Cancel the scheduled change to ${A.label}`,tags:T,responses:{...M(o(N(A)),"The singleton."),"409":r(o("Error"),"Nothing was scheduled.")}}})}return p}function N(c){return c.name}function Q(c){return`${c.name}Input`}function Y(c){if(c===void 0||c.length===0)throw e.validation("A document id is required.");return c}var qt={id:{type:"string"},createdAt:{type:"string",format:"date-time"},updatedAt:{type:"string",format:"date-time"},updatedBy:{type:["string","null"]},deletedAt:{type:["string","null"],format:"date-time",description:"Set while the document is in the trash."},purgeAfter:{type:["string","null"],format:"date-time"},scheduledAt:{type:["string","null"],format:"date-time"},scheduledPatch:{type:["object","null"],description:"The field values a scheduled change will write."},_localeFields:{type:"array",items:{type:"string"},description:"Localized fields with a stored value (including null) in the requested locale, independent of defaults and fallback."},_fallback:{type:"object",additionalProperties:{type:"string"},description:"Which fields were answered from i18n.defaultLocale. Absent when the requested locale had every value."}};function kn(c,u){let w=c._config,p=Object.create(null);for(let j of u){let A=Jt(j.path),S=p[A]??{};S[j.method.toLowerCase()]=Ot(j),p[A]=S}return{openapi:"3.1.0",info:{title:`${w.admin.title??"Heyo CMS"} — content API`,version:Ft(p),description:["Generated from the Heyo CMS configuration. Every endpoint below is served by `cms.handler`.","","Filters accept two syntaxes: `?status=draft` / `?views[gte]=10` for the simple cases, and `?where=` carrying the JSON filter AST for composed ones.","A `204` on a write means a `before` hook stopped the operation; it is not an error."].join(`
|
|
2
|
-
`)},servers:[{url:w.basePath}],tags:Et(c),security:[{bearerAuth:[]},{sessionCookie:[]}],components:{securitySchemes:{bearerAuth:{type:"http",scheme:"bearer",description:"A session token or an API key. The key prefix tells them apart, so one header serves both."},sessionCookie:{type:"apiKey",in:"cookie",name:fe,description:"Set by the sign-in routes; what the panel uses."}},schemas:Pt(c)},paths:p,"x-heyo-cms":{basePath:w.basePath,adminPath:`${w.basePath}${w.admin.path}`,collections:Object.values(w.collections).map((j)=>({name:j.name,slug:j.slug})),globals:Object.values(w.globals).map((j)=>({name:j.name,slug:j.slug})),plugins:w.plugins.map((j)=>j.id)}}}function Ot(c){let u=c.openapi,w=[...u?.parameters??[]];for(let p of xt(c.path))if(!w.some((j)=>j.name===p))w.push({name:p,in:"path",required:!0,schema:{type:"string"}});return{operationId:Dt(c),summary:u?.summary??(c.source==="core"?`${c.method} ${c.path}`:`${c.method} ${c.path} (plugin: ${c.source})`),...u?.description===void 0?{}:{description:u.description},tags:u?.tags??[c.source==="core"?"other":c.source],...w.length===0?{}:{parameters:w},...u?.requestBody===void 0?{}:{requestBody:u.requestBody},responses:{...u?.responses??{"200":{description:"Success."}},"400":{description:"The request could not be read.",content:{"application/json":{schema:Me()}}},"401":{description:"No session, no API key, or a spent credential.",content:{"application/json":{schema:Me()}}}},...u?.security===!1?{security:[]}:{},...c.source==="core"?{}:{"x-heyo-cms-plugin":c.source}}}function Me(){return{$ref:"#/components/schemas/Error"}}function Pt(c){let u=c._config,w={Error:{type:"object",required:["error"],properties:{error:{type:"object",required:["message","code","status"],properties:{message:{type:"string"},code:{type:"string",description:"Machine-readable: not_found, forbidden, validation_failed, conflict, invalid_cursor, …"},status:{type:"integer"},details:{}}}}},Actor:{type:"object",properties:{id:{type:"string"},source:{type:"string",enum:["session","api-key"]},roles:{type:"array",items:{type:"string"}},permissions:{type:"array",items:{type:"string"},description:"Flattened `collection:action` grants."}}},User:{type:"object",properties:{id:{type:"string"},email:{type:"string",format:"email"},name:{type:["string","null"]},status:{type:"string",enum:["active","invited","disabled"]},roles:{type:"array",items:{type:"string"}},avatarUrl:{type:["string","null"]},locale:{type:["string","null"]},twoFactorEnabled:{type:"boolean"},lastLoginAt:{type:["string","null"],format:"date-time"},createdAt:{type:"string",format:"date-time"},updatedAt:{type:"string",format:"date-time"}}},Invite:{type:"object",properties:{token:{type:"string",description:"Single-use. The CMS does not send email; you deliver it."},expiresAt:{type:"string",format:"date-time"},email:{type:"string",format:"email"},userId:{type:"string"},user:{$ref:"#/components/schemas/User"}}},Role:{type:"object",properties:{name:{type:"string"},label:{type:["string","null"]},permissions:{type:"array",items:{type:"string"}},source:{type:"string",enum:["config","database"],description:"`config` roles are code and cannot be edited here."}}},ApiKey:{type:"object",properties:{id:{type:"string"},name:{type:"string"},prefix:{type:"string"},userId:{type:["string","null"]},scopes:{type:"array",items:{type:"string"}},lastUsedAt:{type:["string","null"],format:"date-time"},expiresAt:{type:["string","null"],format:"date-time"},revokedAt:{type:["string","null"],format:"date-time"},createdAt:{type:"string",format:"date-time"}}},IssuedApiKey:{allOf:[{$ref:"#/components/schemas/ApiKey"},{type:"object",properties:{key:{type:"string",description:"Shown once, never again."}}}]},SignInResult:{oneOf:[{type:"object",required:["status","token"],properties:{status:{type:"string",const:"signed-in"},token:{type:"string"},expiresAt:{type:"string",format:"date-time"},user:{$ref:"#/components/schemas/User"},actor:{$ref:"#/components/schemas/Actor"}}},{type:"object",required:["status","challenge"],properties:{status:{type:"string",const:"two-factor-required"},challenge:{type:"string"},expiresAt:{type:"string",format:"date-time"}},description:"A correct password on an account with a second factor. Worth nothing without a code."}]},Locale:{type:"object",properties:{code:{type:"string"},name:{type:"string",description:'The English name: "Polish".'},rtl:{type:"boolean"},isDefault:{type:"boolean"}}},ActivityEntry:{type:"object",properties:{id:{type:"string"},action:{type:"string"},actorId:{type:["string","null"]},actorSource:{type:["string","null"]},collection:{type:["string","null"]},documentId:{type:["string","null"]},locale:{type:["string","null"]},changes:{type:["object","null"]},ip:{type:["string","null"]},createdAt:{type:["string","null"],format:"date-time"}}},AiProvider:{type:"object",description:"Whether a provider has credentials. Never the credentials.",properties:{provider:{type:"string"},configured:{type:"boolean"},source:{type:["string","null"],enum:["config","database",null]},type:{type:["string","null"]},hint:{type:["string","null"],description:"Last four characters of a stored key."},updatedAt:{type:["string","null"],format:"date-time"}}},AiUsage:{type:"object",properties:{input:{type:"integer"},output:{type:"integer"},total:{type:"integer"},cost:{type:"number",description:"US dollars, as priced by the catalogue."}}},AiResult:{type:"object",description:"A suggestion. The document is unchanged until somebody saves it.",properties:{collection:{type:"string"},field:{type:"string"},action:{type:"string"},value:{description:"Shaped for the field: a string for text, a ProseMirror document for richText, an array for multiselect."},preview:{type:"string",description:"The same thing as text."},model:{type:"object"},usage:{$ref:"#/components/schemas/AiUsage"}}},AiAssistantEvent:{type:"object",description:"One server-sent event from `POST /ai/assistant`. The panel is written against this union; pi's own event vocabulary is never exposed.",properties:{type:{type:"string",enum:["text-delta","tool-start","tool-end","mutation-applied","approval-required","done","error"]},text:{type:"string",description:"`text-delta` only."},id:{type:"string",description:"Tool call id."},label:{type:"string",description:"`tool-start` only."},summary:{type:"string",description:"`tool-end` only. Written by the server from the tool name, never the tool's raw result."},runId:{type:"string"},target:{$ref:"#/components/schemas/AiMutationTarget"},fields:{type:"array",items:{type:"string"}},plan:{$ref:"#/components/schemas/AiPlan"},usage:{$ref:"#/components/schemas/AiUsage"},code:{type:"string",description:"`error` only."},message:{type:"string",description:"`error` only."}}},AiMutationTarget:{type:"object",properties:{kind:{type:"string",enum:["document","global","media"]},collection:{type:"string"},collectionSlug:{type:"string"},id:{type:"string"},locale:{type:["string","null"]},revision:{type:"integer"}}},AiPlan:{type:"object",description:"A change waiting for a human. Field names and labels only: an approval dialog nobody reads is the failure this step exists to prevent.",properties:{id:{type:"string"},runId:{type:"string"},summary:{type:"string"},expiresAt:{type:"string",format:"date-time"},operations:{type:"array",items:{type:"object",properties:{action:{type:"string"},target:{$ref:"#/components/schemas/AiMutationTarget"},label:{type:"string"},fields:{type:"array",items:{type:"string"}}}}}}},Webhook:{type:"object",properties:{id:{type:"string"},url:{type:"string",format:"uri"},events:{type:"array",items:{type:"string"}},filters:{type:["object","null"]},headers:{type:["object","null"]},hasSecret:{type:"boolean",description:"Whether this subscription signs with its own secret."},active:{type:"boolean"},createdAt:{type:["string","null"],format:"date-time"},updatedAt:{type:["string","null"],format:"date-time"}}},WebhookDelivery:{type:"object",properties:{id:{type:"string"},webhookId:{type:"string"},eventId:{type:"string"},eventType:{type:"string"},status:{type:"string",enum:["pending","delivered","failed"]},attempt:{type:"integer"},responseStatus:{type:["integer","null"]},responseBody:{type:["string","null"]},error:{type:["string","null"]},nextAttemptAt:{type:["string","null"],format:"date-time"},deliveredAt:{type:["string","null"],format:"date-time"},createdAt:{type:["string","null"],format:"date-time"},requestBody:{type:["object","null"],description:"The exact body that was signed. Only when asked for."}}},TrashedEntry:{type:"object",properties:{collection:{type:"string"},id:{type:"string"},deletedAt:{type:["string","null"],format:"date-time"},purgeAfter:{type:["string","null"],format:"date-time"},document:{type:"object"}}},JobRunReport:{type:"object",properties:{ranAt:{type:"string",format:"date-time"},processed:{type:"integer"},failed:{type:"integer"},results:{type:"array",items:{type:"object",properties:{job:{type:"string"},processed:{type:"integer"},failed:{type:"integer"},more:{type:"boolean",description:"More was waiting than `limit` allowed."}}}}}},JobFailure:{type:"object",properties:{id:{type:"string"},type:{type:"string"},payload:{type:["object","null"]},error:{type:["string","null"]},attempts:{type:"integer"},createdAt:{type:["string","null"],format:"date-time"}}}};if(u.uploads)w.Media={type:"object",properties:{id:{type:"string"},filename:{type:"string"},mimeType:{type:"string"},size:{type:"integer"},width:{type:["integer","null"]},height:{type:["integer","null"]},storageKey:{type:"string"},checksum:{type:["string","null"]},alt:{type:"object",additionalProperties:{type:"string"}},focalPoint:{type:["object","null"]},crop:{type:["object","null"]},status:{type:"string",enum:["active","orphaned","purging"]},orphanedAt:{type:["string","null"],format:"date-time"},purgeAfter:{type:["string","null"],format:"date-time",description:"When the collector will delete it. `null` means never."},purgeError:{type:["string","null"]},metadata:{type:"object"},variants:{type:"array",items:{type:"string"}},createdBy:{type:["string","null"]},createdAt:{type:["string","null"],format:"date-time"},updatedAt:{type:["string","null"],format:"date-time"},url:{type:"string"}}},w.MediaUsage={type:"object",properties:{mediaId:{type:"string"},collection:{type:"string"},documentId:{type:"string"},field:{type:"string"},locale:{type:"string"},createdAt:{type:["string","null"],format:"date-time"}}};for(let p of[...Object.values(u.collections),...Object.values(u.globals)])w[N(p)]=Ct(p),w[Q(p)]=St(p);return w}function Ct(c){let u={};for(let[w,p]of Object.entries(c.fields))u[w]=Ne(p);return{type:"object",title:c.label,...c.kind==="global"?{description:"A singleton. The timestamps are null until it is first saved."}:{},properties:{...u,...qt}}}function St(c){let u={};for(let[w,p]of Object.entries(c.fields))u[w]=Ne(p);return{type:"object",title:`${c.label} (input)`,description:"A patch. Absent fields are left alone; a field the actor may not write is refused rather than dropped.",properties:u}}function Ne(c){let u;try{let p=Tt.toJSONSchema(c.schema,{io:"input",unrepresentable:"any"});delete p.$schema,u=$t(p)}catch{u=It(c)}let w=c.options;return{...u,...w.label===void 0?{}:{title:w.label},...w.description===void 0?{}:{description:w.description},...c.defaultValue===void 0?{}:{default:c.defaultValue},...w.readOnly===!0?{readOnly:!0}:{},"x-heyo-cms-field":c.type,...c.localized?{"x-heyo-cms-localized":!0}:{},...c.required?{"x-heyo-cms-required":!0}:{},...c.relationTo===void 0?{}:{"x-heyo-cms-relation":c.relationTo}}}function $t(c){let u=c.anyOf;if(!Array.isArray(u)||u.length!==2)return c;let w=u.find((T)=>typeof T==="object"&&T!==null&&T.type==="null"),p=u.find((T)=>T!==w);if(!w||typeof p!=="object"||p===null)return c;let j=p,A=j.type,{anyOf:S,...I}=c;return{...I,...j,...typeof A==="string"?{type:[A,"null"]}:{}}}function It(c){switch(c.column.type){case"integer":case"bigint":return{type:"integer"};case"real":return{type:"number"};case"boolean":return{type:"boolean"};case"timestamp":return{type:"string",format:"date-time"};case"json":return{};default:return{type:"string"}}}function Et(c){let u=c._config,w=[...Object.values(u.collections).map((p)=>({name:p.slug,description:`${p.label}: CRUD, the trash and scheduled changes.`})),...Object.keys(u.globals).length===0?[]:[{name:"globals",description:"Singletons."}],...u.uploads?[{name:"media",description:"The library, the variants and the lifecycle."}]:[],{name:"auth",description:"Editor sign-in, second factor and API keys."},{name:"access",description:"Editors and roles."},{name:"i18n",description:"The language registry."},...u.trash.enabled?[{name:"trash",description:"Deleted documents."}]:[],{name:"activity",description:"The audit trail."},{name:"jobs",description:"The sweeps."},{name:"admin",description:"The panel."},{name:"system",description:"This document."}];for(let p of u.plugins)if(p.routes?.length)w.push({name:p.id,description:`Routes from the ${p.id} plugin.`});return w}function Jt(c){return c.split("/").map((u)=>u.startsWith(":")?`{${u.slice(1)}}`:u==="*"?"{path}":u).join("/")}function xt(c){return c.split("/").filter((u)=>u.startsWith(":")||u==="*").map((u)=>u==="*"?"path":u.slice(1))}function Dt(c){let u=c.path.split("/").filter((w)=>w.length>0).map((w)=>w.startsWith(":")?`by-${w.slice(1)}`:w==="*"?"asset":w);return[c.method.toLowerCase(),...u].join("-").replaceAll(/[^a-zA-Z0-9-]/g,"-")}function Ft(c){let u=JSON.stringify(Object.keys(c).sort()),w=2166136261;for(let p=0;p<u.length;p+=1)w^=u.charCodeAt(p),w=Math.imul(w,16777619)>>>0;return`0.0.0+${w.toString(16).padStart(8,"0")}`}function Rn(c){let u=async(w)=>{let p=await c();return p.transaction((j)=>w(p,j))};return{query:(w)=>u((p,j)=>p.query(j,w)),mutate:(w)=>u((p,j)=>p.mutate(j,w)),find:(w,p)=>u((j,A)=>d(j,A).find(w,p)),findOne:(w,p)=>u((j,A)=>d(j,A).findOne(w,p)),insert:(w,p)=>u((j,A)=>d(j,A).insert(w,p)),update:(w,p,j)=>u((A,S)=>d(A,S).update(w,p,j)),delete:(w,p)=>u((j,A)=>d(j,A).delete(w,p))}}class _e{compiled=[];signatures=new Map;add(c){let u=Nt(c.path,c.source),w=u.at(-1)?.kind==="wildcard",p=`${c.method} ${u.map((A)=>A.kind==="static"?A.value:`{${A.kind}}`).join("/")}`,j=this.signatures.get(p);if(j)throw new n(c.source==="core"?"routes":`plugins.${c.source}.routes`,`"${c.method} ${c.path}" collides with a route already registered by "${j}"`);this.signatures.set(p,c.source),this.compiled.push({...c,segments:u,wildcard:w,specificity:u.filter((A)=>A.kind==="static").length}),this.compiled.sort((A,S)=>Number(A.wildcard)-Number(S.wildcard)||S.specificity-A.specificity||S.segments.length-A.segments.length)}list(){return this.compiled.map(({segments:c,wildcard:u,specificity:w,...p})=>p)}routes(c){return this.compiled.map((u)=>({method:u.method,path:u.path==="/"?c:`${c}${u.path}`,source:u.source,middleware:u.middleware?.length??0}))}match(c,u){let w=Le(u),p=new Set,j=c==="HEAD"?"GET":c;for(let A of this.compiled){let S=Mt(A,w);if(!S)continue;if(A.method===j)return{kind:"found",route:A,params:S};p.add(A.method)}if(p.size>0)return{kind:"method-not-allowed",allowed:[...p].sort()};return{kind:"not-found"}}}function Mt(c,u){if(c.wildcard){if(u.length<c.segments.length-1)return null}else if(u.length!==c.segments.length)return null;let w={};for(let[p,j]of c.segments.entries()){if(j.kind==="wildcard")return w["*"]=u.slice(p).join("/"),w;let A=u[p];if(A===void 0)return null;if(j.kind==="static"){if(j.value!==A)return null;continue}if(A.length===0)return null;w[j.name]=Lt(A)}return w}function Nt(c,u){if(!c.startsWith("/"))throw new n(u==="core"?"routes":`plugins.${u}.routes`,`route path "${c}" must start with "/"`);let w=Le(c);return w.map((p,j)=>{if(p==="*"){if(j!==w.length-1)throw new n(u==="core"?"routes":`plugins.${u}.routes`,`route path "${c}" may only use "*" as its last segment`);return{kind:"wildcard"}}if(p.startsWith(":")){let A=p.slice(1);if(A.length===0)throw new n(u==="core"?"routes":`plugins.${u}.routes`,`route path "${c}" has an unnamed parameter`);return{kind:"param",name:A}}return{kind:"static",value:p}})}function Le(c){return c.split("/").filter((u)=>u.length>0)}function Lt(c){try{return decodeURIComponent(c)}catch{return c}}function Be(c){let u=c._config;if(!u.admin.auth)return[];let w=["access"],p=[{method:"GET",path:"/users",source:"core",handler:async(j)=>{m(u,j.actor,"users:read");let A=j.query.get("status"),S=j.query.get("search"),I=R(j.query.get("limit"),"limit",1,200),T=R(j.query.get("offset"),"offset",0,1e5),[q,O]=await Promise.all([c.auth.users.list({...A===null?{}:{status:Ue(A)},...S===null?{}:{search:S},...I===void 0?{}:{limit:I},...T===void 0?{}:{offset:T}}),c.auth.users.count()]);return i({users:q,totalUsers:O})},openapi:{summary:"List editors",tags:w,parameters:[a("status","string","active, invited or disabled.",{enum:["active","invited","disabled"]}),a("search","string","Matches the email or the name."),a("limit","integer","Page size. Defaults to 50."),a("offset","integer","Rows to skip.")],responses:{"200":r({type:"object",properties:{users:{type:"array",items:o("User")},totalUsers:{type:"integer"}}},"The editors of this CMS.")}}},{method:"GET",path:"/users/:id",source:"core",handler:async(j)=>{m(u,j.actor,"users:read");let A=await c.auth.users.get(j.params.id);if(!A)throw e.notFound("No such user.");return i({user:A})},openapi:{summary:"Read one editor",tags:w,parameters:[l("id","User id.")],responses:{"200":r({type:"object",properties:{user:o("User")}},"The user."),"404":r(o("Error"),"No such user.")}}},{method:"PATCH",path:"/users/:id",source:"core",handler:async(j)=>{let A=m(u,j.actor,"users:update"),S=await f(j.request),I=ve(S,"roles"),T=F(S,"name"),q=F(S,"locale"),O=F(S,"status"),J=await c.auth.users.update(j.params.id,{actor:A,...T===void 0?{}:{name:T},...I===void 0?{}:{roles:I},...q===void 0?{}:{locale:q},...O===void 0?{}:{status:Ue(O)}});return i({user:J})},openapi:{summary:"Update an editor",description:"A role change emits `role.changed` and takes effect on the user's next request, because permissions are resolved per request rather than frozen into the session.",tags:w,parameters:[l("id","User id.")],requestBody:h({type:"object",properties:{name:{type:["string","null"]},roles:{type:"array",items:{type:"string"}},status:{type:"string",enum:["active","invited","disabled"]},locale:{type:["string","null"]}}}),responses:{"200":r({type:"object",properties:{user:o("User")}},"The user.")}}},{method:"POST",path:"/users/invite",source:"core",handler:async(j)=>{let A=m(u,j.actor,"users:invite"),S=await f(j.request),I=ve(S,"roles"),T=F(S,"name"),q=await c.auth.users.invite({email:v(S,"email"),actor:A,...I===void 0?{}:{roles:I},...T===void 0?{}:{name:T}});return i(q,201)},openapi:{summary:"Invite an editor",description:"Creates the account in `invited` state and returns the single-use token, because the CMS does not send email. `user.invited` carries who was invited and never the token.",tags:w,requestBody:h({type:"object",required:["email"],properties:{email:{type:"string",format:"email"},name:{type:"string"},roles:{type:"array",items:{type:"string"}}}}),responses:{"201":r(o("Invite"),"The invitation and its token."),"409":r(o("Error"),"That address already has an account.")}}},{method:"DELETE",path:"/users/:id",source:"core",handler:async(j)=>{let A=m(u,j.actor,"users:delete"),S=j.params.id;if(S===A.id)throw e.conflict("You cannot remove your own account.");return await c.auth.users.remove(S,{actor:A}),G()},openapi:{summary:"Remove an editor",description:"Their sessions, accounts, tokens and API keys go with them. Documents they wrote do not.",tags:w,parameters:[l("id","User id.")],responses:{"204":{description:"Removed."},"409":r(o("Error"),"You cannot remove your own account.")}}},{method:"GET",path:"/roles",source:"core",handler:async(j)=>{m(u,j.actor,"roles:read");let A=await c.auth.roles.list();return i({roles:A})},openapi:{summary:"List roles",description:"Both kinds: the ones declared in `rbac.roles`, which are code, and the ones created in the panel, which are rows. `source` says which is which.",tags:w,responses:{"200":r({type:"object",properties:{roles:{type:"array",items:o("Role")}}},"The roles.")}}}];if(u.rbac?.customRoles===!0)p.push({method:"POST",path:"/roles",source:"core",handler:async(j)=>{m(u,j.actor,"roles:create");let A=await f(j.request),S=ve(A,"permissions")??[],I=F(A,"label"),T=await c.auth.roles.create({name:v(A,"name"),permissions:S,...I===void 0?{}:{label:I}});return i({role:T},201)},openapi:{summary:"Create a role",tags:w,requestBody:h({type:"object",required:["name","permissions"],properties:{name:{type:"string"},label:{type:"string"},permissions:{type:"array",items:{type:"string"},description:"`collection:action`, with `*` allowed on either side."}}}),responses:{"201":r({type:"object",properties:{role:o("Role")}},"The role."),"409":r(o("Error"),"A role with that name exists, or the name is declared in the configuration.")}}},{method:"PATCH",path:"/roles/:name",source:"core",handler:async(j)=>{m(u,j.actor,"roles:update");let A=await f(j.request),S=ve(A,"permissions"),I=F(A,"label"),T=await c.auth.roles.update(j.params.name,{...S===void 0?{}:{permissions:S},...I===void 0?{}:{label:I}});return i({role:T})},openapi:{summary:"Update a role",tags:w,parameters:[l("name","Role name.")],requestBody:h({type:"object",properties:{label:{type:["string","null"]},permissions:{type:"array",items:{type:"string"}}}}),responses:{"200":r({type:"object",properties:{role:o("Role")}},"The role."),"404":r(o("Error"),"No such role, or it is declared in the configuration.")}}},{method:"DELETE",path:"/roles/:name",source:"core",handler:async(j)=>{if(m(u,j.actor,"roles:delete"),!await c.auth.roles.remove(j.params.name))throw e.notFound("No such role.");return G()},openapi:{summary:"Delete a role",description:"A user still holding it keeps the name and loses the grants, because the safe reading of a grant that no longer exists is no grant.",tags:w,parameters:[l("name","Role name.")],responses:{"204":{description:"Removed."},"404":r(o("Error"),"No such role.")}}});return p}function Ue(c){if(c==="active"||c==="invited"||c==="disabled")return c;throw e.validation(`"${c}" is not a status; use active, invited or disabled.`)}function We(c){let u=c._config,w=u.admin.path===""?"/":u.admin.path,p=u.admin.assets;p?.configure?.({basePath:u.basePath,panelPath:`${u.basePath}${u.admin.path}`,title:u.admin.title??"Heyo CMS"});let j=async(A,S)=>{if(!p)return Bt(c);let I=await p.asset(A)??(_t(A)?null:await p.asset(""));if(!I)return i({error:{message:"Not found.",code:"not_found",status:404}},404);let T=I.etag;if(T&&S.headers.get("if-none-match")===T)return new Response(null,{status:304,headers:{etag:T}});return new Response(I.body,{status:200,headers:{"content-type":I.contentType,"cache-control":I.cacheControl??(Ut(A)?"public, max-age=31536000, immutable":"no-cache"),...T?{etag:T}:{}}})};return[{method:"GET",path:w,source:"core",handler:(A)=>j("",A.request),openapi:{summary:"The admin panel",description:"The panel's HTML shell. Everything below it is the same single-page application.",tags:["admin"],security:!1,responses:{"200":{description:"HTML."}}}},{method:"GET",path:w==="/"?"/*":`${w}/*`,source:"core",handler:(A)=>j(A.params["*"]??"",A.request),openapi:{summary:"The admin panel's files and deep links",tags:["admin"],security:!1,parameters:[l("*","Asset path, or a panel route.")],responses:{"200":{description:"The asset, or the shell for a panel route."},"304":{description:"The cached copy is current."},"404":{description:"No such asset."}}}}]}function ze(c){return{method:"GET",path:"/openapi.json",source:"core",handler:()=>i(c()),openapi:{summary:"This document",description:"Generated from the configuration and the registered routes, including the ones plugins brought. It is the contract: a generated client, Postman and curl all read the same source.",tags:["system"],security:!1,responses:{"200":{description:"An OpenAPI 3.1 document."}}}}}function _t(c){return(c.split("/").at(-1)??"").includes(".")}function Ut(c){return/[.-][0-9a-f]{8,}\.[a-z0-9]+$/i.test(c)}function Bt(c){let u=c._config,w=u.basePath,p=Object.values(u.collections),j=`<!doctype html>
|
|
3
|
-
<html lang="en">
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="utf-8" />
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
-
<title>${V(u.admin.title??"Heyo CMS")}</title>
|
|
8
|
-
<style>
|
|
9
|
-
:root { color-scheme: light dark; }
|
|
10
|
-
body { font: 15px/1.6 ui-sans-serif, system-ui, sans-serif; margin: 0 auto; max-width: 46rem; padding: 4rem 1.5rem; }
|
|
11
|
-
h1 { font-size: 1.4rem; margin: 0 0 .25rem; }
|
|
12
|
-
p { color: color-mix(in oklab, currentColor 70%, transparent); }
|
|
13
|
-
code { font-family: ui-monospace, monospace; font-size: .9em; }
|
|
14
|
-
ul { padding-left: 1.1rem; }
|
|
15
|
-
a { color: inherit; }
|
|
16
|
-
</style>
|
|
17
|
-
</head>
|
|
18
|
-
<body>
|
|
19
|
-
<h1>${V(u.admin.title??"Heyo CMS")}</h1>
|
|
20
|
-
<p>
|
|
21
|
-
The API is mounted at <code>${V(w)}</code> and answering.
|
|
22
|
-
The panel is not installed: <code>admin.assets</code> is not configured.
|
|
23
|
-
Install <code>@heyo-sh/heyo-cms-admin</code> and pass
|
|
24
|
-
<code>assets: adminAssets()</code>.
|
|
25
|
-
</p>
|
|
26
|
-
<ul>
|
|
27
|
-
<li><a href="${V(w)}/openapi.json">openapi.json</a> — every route this deployment answers</li>
|
|
28
|
-
<li><a href="${V(w)}/panel">panel</a> — what the panel would render here</li>
|
|
29
|
-
<li><a href="${V(w)}/auth/session">auth/session</a> — who you are right now</li>
|
|
30
|
-
${p.map((A)=>` <li><a href="${V(w)}/${V(A.slug)}">${V(A.slug)}</a></li>`).join(`
|
|
31
|
-
`)}
|
|
32
|
-
</ul>
|
|
33
|
-
</body>
|
|
34
|
-
</html>
|
|
35
|
-
`;return new Response(j,{status:200,headers:{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}})}function V(c){return c.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}function Ke(c){let u=c._config;if(!u.ai)return[];let w=[],p=[...Object.values(u.collections),...Object.values(u.globals)];for(let j of p){let A=j.kind==="global"?`/globals/${j.slug}`:`/${j.slug}`,S=Object.values(j.fields).some((I)=>I.aiGenerate!==void 0||I.ai!==void 0&&Object.keys(I.ai).length>0);if(Object.values(j.fields).some((I)=>I.localized))w.push({method:"POST",path:j.kind==="global"?`${A}/ai/translate-variant`:`${A}/:id/ai/translate-variant`,source:"core",handler:async(I)=>{let T=await f(I.request),q=v(T,"locale"),O=v(T,"sourceLocale");if(q===O||!u.i18n.locales.includes(q)||!u.i18n.locales.includes(O))throw e.validation("Choose two different configured languages.");if(!Array.isArray(T.fields)||T.fields.some((x)=>typeof x!=="string"))throw e.validation("fields must be an array of field names.");let J={};for(let x of new Set(T.fields)){let D=j.fields[x];if(!D?.localized||!["text","textarea","richText","email","url"].includes(D.type))throw e.validation(`Cannot translate ${x}.`);let L=await c.ai.run({collection:j.name,field:x,action:"translate",variantTranslation:!0,...j.kind==="global"?{}:{id:I.params.id},actor:I.actor,source:y(I.request),locale:q,sourceLocale:O,signal:I.request.signal});J[x]=L.value}return i({values:J})},openapi:{summary:`Translate localized fields of a ${j.label} language variant`,description:"Returns translated values without writing them. Only localized text fields are translated; the caller creates the variant through the ordinary conditional PATCH.",tags:["ai"],parameters:j.kind==="global"?[]:[l("id","Document ID.")],requestBody:h({type:"object",required:["locale","sourceLocale","fields"],properties:{locale:{type:"string"},sourceLocale:{type:"string"},fields:{type:"array",items:{type:"string"}}}}),responses:{"200":r({type:"object",properties:{values:{type:"object"}}},"Translated field values."),"403":r(o("Error"),"The actor may not update a field."),"422":r(o("Error"),"Invalid languages or fields.")}}});if(S){let I=async(T,q)=>{let O=await Qt(T.request),J=O.document,x=T.query.get("locale")??Ge(O.locale),D=T.query.get("sourceLocale")??Ge(O.sourceLocale),L=await c.ai.run({collection:j.name,field:T.params.field,action:T.params.action,actor:T.actor,source:y(T.request),...q===void 0?{}:{id:q},...Ve(J)?{document:J}:{},...x===void 0?{}:{locale:x},...D===void 0?{}:{sourceLocale:D},signal:T.request.signal});return i(L)};w.push({method:"POST",path:`${A}/:id/ai/:field/:action`,source:"core",handler:(T)=>I(T,T.params.id),openapi:He(j,!0)},{method:"POST",path:`${A}/ai/:field/:action`,source:"core",handler:(T)=>I(T),openapi:He(j,!1)})}}return w.push(...Wt(c)),w.push(...Vt(c)),w}function Wt(c){let u=c._config;if(u.ai?.assistant?.enabled===!1)return[];let w=["ai"];return[{method:"POST",path:"/ai/assistant",source:"core",handler:async(p)=>{let j=m(u,p.actor,"ai:use"),A=await f(p.request),S=Qn(A.pageContext);return zt((I)=>c.ai.runAssistant({message:v(A,"message"),history:Ht(A.history),actor:j,source:y(p.request),signal:I,...typeof A.conversationId==="string"?{conversationId:A.conversationId}:{},...typeof A.locale==="string"?{locale:A.locale}:{},...S===void 0?{}:{pageContext:S}}),p.request)},openapi:{summary:"Talk to the assistant",description:"Server-sent events. The agent reads and writes through the ordinary API with the caller's own permissions, so every change it makes runs the same validation, hooks, events and activity log as a form save — with `source: ai` and the signed-in human as the actor.\n\nCreating, deleting and multi-record changes never happen here: they arrive as `approval-required` and are executed by the approval endpoint.",tags:w,requestBody:h({type:"object",required:["message"],properties:{message:{type:"string",maxLength:12000},conversationId:{type:"string"},locale:{type:"string",description:"The language being edited, for a request with no `pageContext`. `pageContext.locale` wins when both are present."},history:{type:"array",maxItems:20,items:{type:"object",properties:{role:{type:"string",enum:["user","assistant"]},text:{type:"string"}}}},pageContext:{type:"object",description:"Where the editor is looking. A hint: every slug, id and locale in it is re-resolved server-side against the configuration and re-read with the caller's permissions.",properties:{kind:{type:"string",enum:["dashboard","collection-list","document","global","media","trash","settings"]},collectionSlug:{type:"string"},documentId:{type:"string"},mediaId:{type:"string",description:`The file the media screen's details pane is showing, so "this image" resolves.`},tab:{type:"string",description:"Which sub-surface of the screen is in front: a rich-text tab, a settings tab, the media status."},locale:{type:"string"},dirtyFields:{type:"array",items:{type:"string"},description:"Names only. The unsaved values stay in the browser; the assistant refuses to write a record whose form is dirty."},baselineRevision:{type:"integer"}}}}}),responses:{"200":{description:"A stream of `AiAssistantEvent`, one per SSE message.",content:{"text/event-stream":{schema:o("AiAssistantEvent")}}},"403":r(o("Error"),"The actor does not have `ai:use`."),"501":r(o("Error"),"`ai_assistant_runtime_missing` or `ai_credentials_missing`.")}}},{method:"POST",path:"/ai/assistant/plans/:id/approve",source:"core",handler:async(p)=>{let j=m(u,p.actor,"ai:use"),A=await c.ai.approveAssistantPlan({planId:p.params.id,actor:j,source:y(p.request),signal:p.request.signal});return i(A)},openapi:{summary:"Apply a plan the editor approved",description:"Executes the stored plan exactly as it was shown. The model is not consulted: the session, the permissions and the revisions are checked again, and the recorded operations run through the ordinary write path.",tags:w,parameters:[l("id","Plan id from `approval-required`.")],responses:{"200":r({type:"object",properties:{planId:{type:"string"},runId:{type:"string"},applied:{type:"array",items:{type:"object",properties:{target:o("AiMutationTarget"),fields:{type:"array",items:{type:"string"}}}}}}},"What was written."),"404":r(o("Error"),"No such plan for this actor."),"409":r(o("Error"),"Already applied, or a record moved on."),"410":r(o("Error"),"`ai_plan_expired`.")}}}]}function zt(c,u){let w=new TextEncoder,p=new AbortController,j=()=>p.abort(),A=p.signal;u.signal.addEventListener("abort",j,{once:!0});let S=c(A)[Symbol.asyncIterator](),I=new ReadableStream({async start(T){let q=!1,O=(J)=>{if(q)return;try{T.enqueue(w.encode(`data: ${JSON.stringify(J)}
|
|
36
|
-
|
|
37
|
-
`))}catch{q=!0}};try{for(;;){let J=await S.next();if(J.done||A.aborted)break;O(J.value)}}catch(J){if(!A.aborted){let x=J instanceof e?J:null;if(O({type:"error",code:x?.code??"ai_assistant_failed",message:x?.message??"The assistant failed."}),!x)console.error("[heyo-cms] the AI assistant failed",J)}}finally{u.signal.removeEventListener("abort",j),q=!0;try{T.close()}catch{}}},cancel(){j(),S.return?.().catch(()=>{return})}});return new Response(I,{headers:{"content-type":"text/event-stream; charset=utf-8","cache-control":"no-cache, no-transform",connection:"keep-alive","x-accel-buffering":"no"}})}function Ht(c){if(!Array.isArray(c))return[];let u=[];for(let w of c){if(!Ve(w))continue;let{role:p,text:j}=w;if(p!=="user"&&p!=="assistant")continue;if(typeof j!=="string"||j.trim().length===0)continue;u.push({role:p,text:j})}return u}function Vt(c){let u=c._config,w=["ai"];return[{method:"GET",path:"/ai/providers",source:"core",handler:async(p)=>{m(u,p.actor,"ai:read");let j=await c.ai.providers();return i({providers:j,defaultModel:u.ai?.defaultModel??null,assistant:u.ai?.assistant?.enabled!==!1,storage:u.ai?.storage?.secret!==void 0})},openapi:{summary:"Which AI providers have credentials",description:"Never the keys themselves: `hint` is the last four characters, `source` says whether the key is in the configuration or in the database.",tags:w,responses:{"200":r({type:"object",properties:{providers:{type:"array",items:o("AiProvider")},defaultModel:{type:["object","null"]},assistant:{type:"boolean"},storage:{type:"boolean",description:"Whether keys may be stored from the panel."}}},"The provider list.")}}},{method:"PUT",path:"/ai/providers/:provider",source:"core",handler:async(p)=>{let j=m(u,p.actor,"ai:manage"),A=await f(p.request),S=await c.ai.setCredential({provider:p.params.provider,token:v(A,"token"),actor:j,source:y(p.request)});return i({provider:S})},openapi:{summary:"Store a provider key",description:"Encrypted with `ai.storage.secret` before it is written. Without that secret the endpoint answers 501, because storing a key in plaintext is not a lesser version of this feature.",tags:w,parameters:[l("provider","Provider id, e.g. `openai`.")],requestBody:h({type:"object",required:["token"],properties:{token:{type:"string"}}}),responses:{"200":r({type:"object",properties:{provider:o("AiProvider")}},"The stored key, described."),"501":r(o("Error"),"ai.storage.secret is not configured.")}}},{method:"DELETE",path:"/ai/providers/:provider",source:"core",handler:async(p)=>{let j=m(u,p.actor,"ai:manage");if(!await c.ai.removeCredential({provider:p.params.provider,actor:j}))throw e.notFound("No stored key for that provider.");return i({removed:!0})},openapi:{summary:"Forget a stored provider key",description:"Removes the database copy. A key in `ai.auth` is in the configuration and is unaffected.",tags:w,parameters:[l("provider","Provider id.")],responses:{"200":r({type:"object",properties:{removed:{type:"boolean"}}},"Removed."),"404":r(o("Error"),"There was no stored key.")}}}]}function He(c,u){let w=Object.entries(c.fields).filter(([,p])=>p.aiGenerate!==void 0||p.ai).map(([p,j])=>`${p}: ${[...j.aiGenerate===void 0?[]:["generate"],...Object.keys(j.ai??{})].join(", ")}`);return{summary:`Run an AI action on a ${c.label} field`,description:["Answers with a value. Nothing is written: the panel inserts the result into the form and the editor saves it, like any other edit (section 8).",u?"The stored document is read first and the draft in the body is merged over it.":"For a document that has not been saved yet; everything the model sees comes from the body.",w.length>0?`Configured here — ${w.join("; ")}.`:""].filter((p)=>p.length>0).join(`
|
|
38
|
-
|
|
39
|
-
`),tags:["ai"],parameters:[l("field","Field name."),l("action","`generate` for aiGenerate, or a key of the legacy `ai` map."),a("locale","string","Language the value is written in."),a("sourceLocale","string","Language `translate` reads from.")],requestBody:h({type:"object",properties:{document:{type:"object",description:"The form as it stands in the browser."},locale:{type:"string"},sourceLocale:{type:"string"}}},!1),responses:{"200":r(o("AiResult"),"The suggestion."),"403":r(o("Error"),"The actor may not write that field."),"404":r(o("Error"),"The field has no such action configured."),"501":r(o("Error"),"This deployment has no `ai` section.")}}}async function Qt(c){let u=c.headers.get("content-length");if(u==="0"||u===null)return{};try{return await f(c)}catch{return{}}}function Ve(c){return typeof c==="object"&&c!==null&&!Array.isArray(c)}function Ge(c){return typeof c==="string"&&c.length>0?c:void 0}function Qe(c){let u=c._config,w=[];for(let p of[...Object.values(u.collections),...Object.values(u.globals)]){if(!Object.values(p.fields).some((I)=>I.generate))continue;let j=p.kind==="global"?`/globals/${p.slug}`:`/${p.slug}`,A=async(I,T)=>{let q=I.params.field,O=p.fields[q];if(!O?.generate)throw e.notFound(`No generator for ${p.name}.${q}.`);let J=await f(I.request),x=typeof J.locale==="string"?J.locale:u.i18n.defaultLocale;if(!u.i18n.locales.includes(x))throw e.validation(`Unknown locale "${x}".`);let D=I.actor,L=Yt(J.document)?J.document:{},W=p.kind==="global"||T?"update":"create",Z=W==="update"?await C(p,{actor:D,operation:W,locale:x,rbac:u.rbac}):void 0,U=await Zt(c,p,T,D,x);if(O.access?.read&&!O.access.read({actor:D,locale:x,record:U}))throw e.notFound(`No generator for ${p.name}.${q}.`);let le=await C(p,{actor:D,operation:W,locale:x,rbac:u.rbac,...T||p.kind==="global"?{record:U}:{}});if(Z||le){if(W==="create")throw new e(`access.create on "${p.name}" returned a filter; a create has no row to filter. Return true or false.`,{status:500,code:"invalid_access_rule"});let z=await c.database();if((await z.transaction((bt)=>z.query(bt,{table:g,where:s(t("id",String(U.id)),t("collection",p.slug),t("deleted_at",null),...Z?[Z]:[],...le?[le]:[]),limit:1}))).length===0)throw e.notFound(`No ${p.name} with id "${U.id}".`)}_(p,{[q]:null},D,x,W==="create"?void 0:U);let Ae={};for(let[z,me]of Object.entries(p.fields)){if(z===q)continue;if(me.access?.read&&!me.access.read({actor:D,locale:x,record:U}))continue;if(z in L||z in U)Ae[z]=z in L?L[z]??null:U[z]??null}let gt=await O.generate({fields:Ae,locale:x}),pe=O.schema.safeParse(gt);if(!pe.success)throw e.validation(`${p.name}.${q}: generated value is invalid: ${pe.error.issues[0]?.message??"invalid value"}`);return i({value:pe.data})},S=(I)=>({summary:`Generate a ${p.label} field without AI`,tags:["content"],parameters:[l("field","Field with a generate function."),...I?[l("id","Document ID.")]:[]],requestBody:h({type:"object",properties:{document:{type:"object"},locale:{type:"string"}}}),responses:{"200":r({type:"object",properties:{value:{}}},"Generated field value.")}});if(p.kind!=="global")w.push({method:"POST",path:`${j}/:id/generate/:field`,source:"core",handler:(I)=>A(I,I.params.id),openapi:S(!0)});w.push({method:"POST",path:`${j}/generate/:field`,source:"core",handler:(I)=>A(I),openapi:S(!1)})}return w}async function Zt(c,u,w,p,j){if(u.kind==="global"){let I=c.globals[u.name];return I?I.get({actor:p,locale:j}):{}}if(!w)return{};let S=await c.api[u.name]?.findById(w,{actor:p,locale:j});if(!S)throw e.notFound(`No ${u.name} with id "${w}", or it is not readable.`);return S}function Yt(c){return typeof c==="object"&&c!==null&&!Array.isArray(c)}function tt(c){let u=c._config,w=u.admin.auth;if(!w)return[];let p=new Set(w.methods),j=["auth"],A=[],S=(T,q)=>{if(T.status!=="signed-in")return i({status:T.status,challenge:T.challenge,expiresAt:T.expiresAt},200);return i({status:T.status,token:T.token,expiresAt:T.expiresAt,user:T.user,actor:T.actor},200,{"set-cookie":Ye(T.token,T.expiresAt,q,u.basePath)})};if(p.has("password")&&w.firstUser!==!1)A.push({method:"POST",path:"/auth/setup",source:"core",handler:async(T)=>{let q=await f(T.request),O=F(q,"name"),J=await c.auth.setup.claim({email:v(q,"email"),password:v(q,"password"),...O===void 0?{}:{name:O},...X(T.request)});return S(J,T.request)},openapi:{summary:"Claim a CMS that has no accounts",description:"Creates the first editor and signs it in. Answers 409 once any account exists, including one created by a request that arrived a millisecond earlier: the count is taken inside the transaction that does the insert. Disable with `admin.auth.firstUser: false`.",tags:j,security:!1,requestBody:h({type:"object",required:["email","password"],properties:{email:{type:"string",format:"email"},password:{type:"string",minLength:8},name:{type:"string"}}}),responses:{"200":r(o("SignInResult"),"A session for the first editor."),"409":r(o("Error"),"Somebody got here first. Sign in.")}}});if(p.has("password"))A.push({method:"POST",path:"/auth/sign-in",source:"core",handler:async(T)=>{let q=await f(T.request),O=await c.auth.password.signIn({email:v(q,"email"),password:v(q,"password"),...X(T.request)});return S(O,T.request)},openapi:{summary:"Sign in with a password",description:'Answers either a session or `{ status: "two-factor-required", challenge }`. There is no way to turn the second into the first without a valid code.',tags:j,security:!1,requestBody:h({type:"object",required:["email","password"],properties:{email:{type:"string",format:"email"},password:{type:"string"}}}),responses:{"200":r(o("SignInResult"),"A session, or a challenge."),"401":r(o("Error"),"Wrong credentials, in constant time.")}}});if(A.push({method:"GET",path:"/auth/session",source:"core",handler:async(T)=>{if(!T.actor)return i({actor:null,user:null});let q=await c.auth.users.get(T.actor.id);return i({actor:T.actor,user:q})},openapi:{summary:"Who is calling",description:"Resolves the session cookie or the `Authorization` header. Answers `{ actor: null }` rather than 401 when there is no caller.",tags:j,security:!1,responses:{"200":r({type:"object",properties:{actor:{oneOf:[o("Actor"),{type:"null"}]},user:{oneOf:[o("User"),{type:"null"}]}}},"The caller, if any.")}}},{method:"POST",path:"/auth/sign-out",source:"core",handler:async(T)=>{let q=Xt(T.request);if(q)await c.auth.sessions.revoke(q);return G({"set-cookie":er(T.request,u.basePath)})},openapi:{summary:"Sign out",description:"Revokes the session server-side and clears the cookie. Idempotent: signing out twice is not an error.",tags:j,responses:{"204":{description:"The session is gone."}}}}),p.has("magic-link")){let T=w.deliverToken;if(T)A.push({method:"POST",path:"/auth/magic-link",source:"core",handler:async(q)=>{let O=await f(q.request),J=await c.auth.magicLink.request({email:v(O,"email")});return await Ze(T,"magic-link",J,q.request,c),i({status:"sent"})},openapi:{summary:"Request a magic link",description:"Mints a single-use token and hands it to `admin.auth.deliverToken`. The response never contains the token and never says whether the address exists.",tags:j,security:!1,requestBody:h({type:"object",required:["email"],properties:{email:{type:"string",format:"email"}}}),responses:{"200":r({type:"object"},'`{ status: "sent" }`.')}}});A.push({method:"POST",path:"/auth/magic-link/verify",source:"core",handler:async(q)=>{let O=await f(q.request),J=await c.auth.magicLink.verify({token:v(O,"token"),...X(q.request)});return S(J,q.request)},openapi:{summary:"Exchange a magic link for a session",tags:j,security:!1,requestBody:h({type:"object",required:["token"],properties:{token:{type:"string"}}}),responses:{"200":r(o("SignInResult"),"A session, or a challenge."),"401":r(o("Error"),"The token is spent, expired or unknown.")}}})}if(p.has("password")){let T=w.deliverToken;if(T)A.push({method:"POST",path:"/auth/password/forgot",source:"core",handler:async(q)=>{let O=await f(q.request),J=await c.auth.password.requestReset({email:v(O,"email")});return await Ze(T,"password-reset",J,q.request,c),i({status:"sent"})},openapi:{summary:"Request a password reset",description:"Same shape as the magic link, and the same silence about whether the address exists.",tags:j,security:!1,requestBody:h({type:"object",required:["email"],properties:{email:{type:"string",format:"email"}}}),responses:{"200":r({type:"object"},'`{ status: "sent" }`.')}}});A.push({method:"POST",path:"/auth/password/reset",source:"core",handler:async(q)=>{let O=await f(q.request),J=await c.auth.password.reset({token:v(O,"token"),password:v(O,"password")});return i({user:J})},openapi:{summary:"Set a new password with a reset token",description:"Every session of that user is revoked: a reset is what somebody does when they believe their password is known to a stranger.",tags:j,security:!1,requestBody:h({type:"object",required:["token","password"],properties:{token:{type:"string"},password:{type:"string",minLength:8}}}),responses:{"200":r({type:"object",properties:{user:o("User")}},"The user."),"401":r(o("Error"),"The token is spent, expired or unknown.")}}})}A.push({method:"POST",path:"/auth/invite/accept",source:"core",handler:async(T)=>{let q=await f(T.request),O=F(q,"password"),J=F(q,"name"),x=await c.auth.users.acceptInvite({token:v(q,"token"),...O===void 0?{}:{password:O},...J===void 0?{}:{name:J},...X(T.request)});return S(x,T.request)},openapi:{summary:"Accept an invitation",description:"Turns an invited account into an active one and signs it in. The token comes from `POST /users/invite`, which an administrator calls.",tags:j,security:!1,requestBody:h({type:"object",required:["token"],properties:{token:{type:"string"},password:{type:"string",minLength:8},name:{type:"string"}}}),responses:{"200":r(o("SignInResult"),"A session."),"401":r(o("Error"),"The invitation is spent, expired or unknown.")}}});let I=[...["github","google","microsoft"].filter((T)=>p.has(T)),...w.sso?["oidc"]:[]];if(I.length>0)A.push({method:"GET",path:"/auth/oauth/:provider",source:"core",handler:async(T)=>{let q=et(T.params.provider,I),O=T.query.get("redirectTo"),J=await c.auth.oauth.authorize({provider:q,redirectUri:Xe(T.request,u.basePath,q),...O===null?{}:{redirectTo:O}});return new Response(null,{status:302,headers:{location:J.url}})},openapi:{summary:"Start an OAuth or SSO sign-in",description:`Redirects to the provider. Configured here: ${I.join(", ")}.`,tags:j,security:!1,parameters:[l("provider",I.join(", ")),a("redirectTo","string","Where to land after the callback.")],responses:{"302":{description:"To the provider."},"404":r(o("Error"),"That provider is not configured.")}}},{method:"GET",path:"/auth/oauth/:provider/callback",source:"core",handler:async(T)=>{let q=et(T.params.provider,I),O=T.query.get("code"),J=T.query.get("state");if(!O||!J)throw e.validation("The provider did not return a code and a state.");let x=await c.auth.oauth.callback({provider:q,code:O,state:J,redirectUri:Xe(T.request,u.basePath,q),...X(T.request)}),D=x.redirectTo;if(x.status==="signed-in"&&D)return new Response(null,{status:302,headers:{location:D,"set-cookie":Ye(x.token,x.expiresAt,T.request,u.basePath)}});return S(x,T.request)},openapi:{summary:"Finish an OAuth or SSO sign-in",tags:j,security:!1,parameters:[l("provider",I.join(", ")),a("code","string","From the provider."),a("state","string","From the provider; checked against the stored one.")],responses:{"200":r(o("SignInResult"),"A session, or a challenge."),"302":{description:"To `redirectTo`, with the cookie set."},"401":r(o("Error"),"The state did not match, or the account is unknown.")}}});if(w.twoFactor===!0)A.push({method:"POST",path:"/auth/2fa/begin",source:"core",handler:async(T)=>{let q=Je(T.actor),O=await c.auth.twoFactor.begin(q.id);return i(O)},openapi:{summary:"Start enrolling an authenticator",description:"Returns the secret and the `otpauth://` URI the panel renders as a QR code. The factor is not enabled until a code proves it works.",tags:j,responses:{"200":r({type:"object",properties:{secret:{type:"string"},uri:{type:"string"}}},"The secret and its URI.")}}},{method:"POST",path:"/auth/2fa/enable",source:"core",handler:async(T)=>{let q=Je(T.actor),O=await f(T.request),J=await c.auth.twoFactor.enable({userId:q.id,code:v(O,"code")});return i({user:J})},openapi:{summary:"Confirm the authenticator",tags:j,requestBody:h({type:"object",required:["code"],properties:{code:{type:"string"}}}),responses:{"200":r({type:"object",properties:{user:o("User")}},"The user."),"401":r(o("Error"),"The code is wrong.")}}},{method:"POST",path:"/auth/2fa/disable",source:"core",handler:async(T)=>{let q=Je(T.actor),O=await c.auth.twoFactor.disable(q.id);return i({user:O})},openapi:{summary:"Remove the second factor",tags:j,responses:{"200":r({type:"object",properties:{user:o("User")}},"The user.")}}},{method:"POST",path:"/auth/2fa/verify",source:"core",handler:async(T)=>{let q=await f(T.request),O=await c.auth.twoFactor.complete({challenge:v(q,"challenge"),code:v(q,"code"),...X(T.request)});return S(O,T.request)},openapi:{summary:"Exchange a challenge and a code for a session",description:"The only way a `two-factor-required` answer becomes a session. Five wrong codes destroy the challenge.",tags:j,security:!1,requestBody:h({type:"object",required:["challenge","code"],properties:{challenge:{type:"string"},code:{type:"string"}}}),responses:{"200":r(o("SignInResult"),"A session."),"401":r(o("Error"),"The code is wrong, or the challenge is spent.")}}});if(w.apiKeys?.enabled===!0)A.push({method:"GET",path:"/auth/api-keys",source:"core",handler:async(T)=>{let q=Fe(T.actor),O=await c.auth.apiKeys.list({userId:q.id});return i({keys:O})},openapi:{summary:"List your API keys",description:"Your own keys. The key material is never returned again.",tags:j,responses:{"200":r({type:"object",properties:{keys:{type:"array",items:o("ApiKey")}}},"The caller's keys.")}}},{method:"POST",path:"/auth/api-keys",source:"core",handler:async(T)=>{let q=Je(T.actor),O=await f(T.request),J=ve(O,"scopes"),x=await c.auth.apiKeys.create({name:v(O,"name"),userId:q.id,actor:q,...J===void 0?{}:{scopes:J}});return i(x,201)},openapi:{summary:"Issue an API key",description:"Bound to the caller, and never wider: the scopes are intersected with the caller's own permissions, so a read-only key on an administrator's account is read-only. `key` is shown once.",tags:j,requestBody:h({type:"object",required:["name"],properties:{name:{type:"string"},scopes:{type:"array",items:{type:"string"}}}}),responses:{"201":r(o("IssuedApiKey"),"The key, once."),"403":r(o("Error"),"An API key cannot issue another.")}}},{method:"DELETE",path:"/auth/api-keys/:id",source:"core",handler:async(T)=>{let q=Fe(T.actor),O=T.params.id;if(!(await c.auth.apiKeys.list({userId:q.id})).some((x)=>x.id===O))throw e.notFound("No such API key.");return await c.auth.apiKeys.revoke(O,{actor:q}),G()},openapi:{summary:"Revoke one of your API keys",tags:j,parameters:[l("id","Key id.")],responses:{"204":{description:"Revoked."},"404":r(o("Error"),"Not one of your keys.")}}});return A}async function Ze(c,u,w,p,j){if(!w)return;let A=new URL(p.url),S=u==="magic-link"?"magic-link":"reset-password";await c({type:u,token:w.token,expiresAt:w.expiresAt,email:w.email,userId:w.userId,url:`${A.origin}${j._config.basePath}${j._config.admin.path}/${S}?token=${encodeURIComponent(w.token)}`})}function X(c){let w=c.headers.get("x-forwarded-for")?.split(",")[0]?.trim()??c.headers.get("cf-connecting-ip");return{ip:w&&w.length>0?w:null,userAgent:c.headers.get("user-agent")}}function Xt(c){let u=c.headers.get("authorization");if(u?.toLowerCase().startsWith("bearer "))return u.slice(7).trim();let w=c.headers.get("cookie");if(!w)return null;for(let p of w.split(";")){let[j,...A]=p.trim().split("=");if(j===fe)return A.join("=")}return null}function Ye(c,u,w,p){let j=new URL(w.url).protocol==="https:";return[`${fe}=${c}`,`Path=${p}`,`Expires=${new Date(u).toUTCString()}`,"HttpOnly","SameSite=Lax",...j?["Secure"]:[]].join("; ")}function er(c,u){let w=new URL(c.url).protocol==="https:";return[`${fe}=`,`Path=${u}`,"Max-Age=0","HttpOnly","SameSite=Lax",...w?["Secure"]:[]].join("; ")}function Xe(c,u,w){return`${new URL(c.url).origin}${u}/auth/oauth/${w}/callback`}function et(c,u){if(c===void 0||!u.includes(c))throw e.notFound(`"${c??""}" is not a configured sign-in provider.`);return c}function rt(c){let u=c._config;if(!u.uploads)return[];let w=["media"],p=Object.keys(u.uploads.images?.variants?.sizes??{});return[{method:"POST",path:"/media/upload",source:"core",handler:async(j)=>{m(u,j.actor,"media:create");let A=await tr(j.request),S=await c.media.upload({...A,actor:j.actor,source:y(j.request)});return i(S,201)},openapi:{summary:"Upload a file",description:"`multipart/form-data` with a `file` part, or the raw bytes with `content-type` and `x-heyo-cms-filename`. The MIME type is taken from the bytes, not from what the client called them.",tags:w,requestBody:{required:!0,content:{"multipart/form-data":{schema:{type:"object",required:["file"],properties:{file:{type:"string",format:"binary"},filename:{type:"string"},alt:{type:"string"},locale:{type:"string"},metadata:{type:"string",description:"JSON object."}}}},"application/octet-stream":{schema:{type:"string",format:"binary"}}}},responses:{"201":r(o("Media"),"The stored file."),"413":r(o("Error"),"The file is larger than uploads.limits.maxFileSize."),"415":r(o("Error"),"The MIME type is not in uploads.limits.accept.")}}},{method:"GET",path:"/media",source:"core",handler:async(j)=>{let A=j.query.get("status"),S=j.query.get("mimeType"),I=j.query.get("search"),T=j.query.get("cursor"),q=R(j.query.get("limit"),"limit",1,200),O=await c.media.list({actor:j.actor,...A===null?{}:{status:ar(A)},...S===null?{}:{mimeType:S},...I===null?{}:{search:I},...T===null?{}:{cursor:T},...q===void 0?{}:{limit:q}});return i(O)},openapi:{summary:"List the library",tags:w,parameters:[a("status","string","active, orphaned or purging.",{enum:["active","orphaned","purging"]}),a("mimeType","string","`image/*` wildcards allowed."),a("search","string","Case-insensitive match on the filename."),a("limit","integer","Page size. Defaults to 25.",{minimum:1,maximum:200}),a("cursor","string","Keyset cursor from the previous page.")],responses:{"200":r({type:"object",properties:{docs:{type:"array",items:o("Media")},limit:{type:"integer"},hasNextPage:{type:"boolean"},cursor:{type:["string","null"]}}},"One page of files.")}}},{method:"GET",path:"/media/:id",source:"core",handler:async(j)=>{let A=await c.media.get(te(j.params.id));if(!A)throw e.notFound("No such file.");return i(A)},openapi:{summary:"Read one file",tags:w,parameters:[l("id","Media id.")],responses:yt(o("Media"),"The file.")}},{method:"PATCH",path:"/media/:id",source:"core",handler:async(j)=>{m(u,j.actor,"media:update");let A=await f(j.request),S=await c.media.update({id:te(j.params.id),actor:j.actor,source:y(j.request),...nr(A)});return i(S)},openapi:{summary:"Update a file's metadata",description:"Alternative text, filename, focal point, crop and your own metadata keys. Changing the focal point or the crop discards the variants rendered from the old one.",tags:w,parameters:[l("id","Media id.")],requestBody:h({type:"object",properties:{filename:{type:"string"},alt:{oneOf:[{type:"string"},{type:"object"}],description:"A string writes one locale; an object replaces the map."},locale:{type:"string"},focalPoint:{type:["object","null"],properties:{x:{type:"number",minimum:0,maximum:1},y:{type:"number",minimum:0,maximum:1}}},crop:{type:["object","null"],properties:{x:{type:"integer"},y:{type:"integer"},width:{type:"integer"},height:{type:"integer"}}},metadata:{type:"object"}}}),responses:M(o("Media"),"The file.")}},{method:"DELETE",path:"/media/:id",source:"core",handler:async(j)=>{m(u,j.actor,"media:delete");let A=await c.media.delete({id:te(j.params.id),force:H(j.query.get("force"),"force")===!0,actor:j.actor,source:y(j.request)});return i(A)},openapi:{summary:"Delete a file",description:"Refused, naming the documents, when something still points at it — `?force=true` overrides. This is the one destructive media operation an editor can perform; losing the last reference merely marks the file unused.",tags:w,parameters:[l("id","Media id."),a("force","boolean","Deletes a file documents still reference.")],responses:{"200":r(o("Media"),"The file that was removed."),"409":r(o("Error"),"Documents still reference the file.")}}},{method:"POST",path:"/media/:id/keep",source:"core",handler:async(j)=>{m(u,j.actor,"media:update");let A=await c.media.keep({id:te(j.params.id),actor:j.actor,source:y(j.request)});return i(A)},openapi:{summary:`The panel's "Keep" button`,description:"Clears the purge deadline of an unused file without claiming anything references it.",tags:w,parameters:[l("id","Media id.")],responses:{"200":r(o("Media"),"The file.")}}},{method:"GET",path:"/media/:id/usages",source:"core",handler:async(j)=>{let A=await c.media.usages(te(j.params.id));return i({usages:A})},openapi:{summary:"Where a file is used",description:"Empty for an unused file, by definition.",tags:w,parameters:[l("id","Media id.")],responses:{"200":r({type:"object",properties:{usages:{type:"array",items:o("MediaUsage")}}},"One entry per document, field and locale.")}}},{method:"GET",path:"/media/:id/:variant",source:"core",handler:async(j)=>{let A=j.params.variant??"original",S=await c.media.variant({id:te(j.params.id),...A==="original"?{}:{variant:A},refresh:H(j.query.get("refresh"),"refresh")===!0});if(!S)throw e.notFound("No such file.");let I=`"${S.media.checksum??S.media.id}-${S.variant??"original"}"`;if(j.request.headers.get("if-none-match")===I)return await S.body.cancel(),new Response(null,{status:304,headers:{etag:I}});return new Response(S.body,{status:200,headers:{"content-type":S.contentType,etag:I,"cache-control":"public, max-age=31536000, immutable","x-heyo-cms-cache":S.cached?"hit":"miss",...S.size===null?{}:{"content-length":String(S.size)}}})},openapi:{summary:"Serve a file or one of its sizes",description:p.length===0?"`original` only; this deployment declares no sizes.":`\`original\` or one of: ${p.join(", ")}. Only declared names are accepted — arbitrary dimensions in a URL are how a stranger fills a bucket one pixel at a time.`,tags:w,parameters:[l("id","Media id."),l("variant",`original${p.length===0?"":`, ${p.join(", ")}`}`),a("refresh","boolean","Renders again even if a stored copy exists.")],responses:{"200":{description:"The bytes."},"304":{description:"The cached copy is current."},"404":r(o("Error"),"No such file or no such size.")}}}]}function nt(c){if(!c._config.uploads)return[];return[{method:"POST",path:"/media/collect",source:"core",handler:async(u)=>{m(c._config,u.actor,"jobs:run");let w=R(u.query.get("limit"),"limit",1,1000),p=await c.media.collect(w===void 0?{}:{limit:w});return i(p)},openapi:{summary:"Run the unused-file collector",description:"Deletes files whose deadline has passed, re-checking references immediately before each delete. Also registered as the `media-gc` job.",tags:["jobs"],parameters:[a("limit","integer","Files examined in one pass.")],responses:{"200":r({type:"object",properties:{examined:{type:"integer"},purged:{type:"integer"},reclaimed:{type:"integer"},failed:{type:"integer"}}},"What the sweep did.")}}}]}var Zn=["usages","keep","collect","upload"];async function tr(c){let u=c.headers.get("content-type")??"";if(u.includes("multipart/form-data")){let I=await c.formData(),T=I.get("file");if(T===null)throw e.validation('The form needs a "file" part.');if(typeof T==="string")throw e.validation('"file" has to be a file, not a string.');let q=I.get("metadata"),O=I.get("filename"),J=I.get("alt"),x=I.get("locale");return{file:T,...typeof O==="string"&&O.length>0?{filename:O}:T.name?{filename:T.name}:{},...T.type?{contentType:T.type}:{},...typeof J==="string"?{alt:J}:{},...typeof x==="string"?{locale:x}:{},...typeof q==="string"&&q.length>0?{metadata:rr(q)}:{}}}let w=new Uint8Array(await c.arrayBuffer());if(w.byteLength===0)throw e.validation("The request body is empty.");let p=new URL(c.url),j=c.headers.get("x-heyo-cms-filename")??p.searchParams.get("filename");if(!j)throw e.validation("A raw upload needs a filename: send `x-heyo-cms-filename` or ?filename=.");let A=p.searchParams.get("alt"),S=p.searchParams.get("locale");return{file:w,filename:j,...u.length>0?{contentType:u}:{},...A===null?{}:{alt:A},...S===null?{}:{locale:S}}}function rr(c){try{let u=JSON.parse(c);if(typeof u!=="object"||u===null||Array.isArray(u))throw Error("not an object");return u}catch{throw e.validation('"metadata" has to be a JSON object.')}}function nr(c){let u={};if(typeof c.filename==="string")u.filename=c.filename;if(typeof c.locale==="string")u.locale=c.locale;if(typeof c.alt==="string")u.alt=c.alt;else if(ae(c.alt))u.alt=c.alt;if(ae(c.metadata))u.metadata=c.metadata;if("focalPoint"in c)u.focalPoint=c.focalPoint===null?null:sr(c.focalPoint,"focalPoint");if("crop"in c)u.crop=c.crop===null?null:or(c.crop);return u}function sr(c,u){if(!ae(c))throw e.validation(`"${u}" has to be an object.`);let{x:w,y:p}=c;if(typeof w!=="number"||typeof p!=="number")throw e.validation(`"${u}" needs numeric x and y.`);return{x:w,y:p}}function or(c){if(!ae(c))throw e.validation('"crop" has to be an object.');let{x:u,y:w,width:p,height:j}=c;if(typeof u!=="number"||typeof w!=="number"||typeof p!=="number"||typeof j!=="number")throw e.validation('"crop" needs numeric x, y, width and height.');return{x:u,y:w,width:p,height:j}}function ae(c){return typeof c==="object"&&c!==null&&!Array.isArray(c)}function ar(c){if(c==="active"||c==="orphaned"||c==="purging")return c;throw e.validation(`"${c}" is not a media status; use active, orphaned or purging.`)}function te(c){if(c===void 0||c.length===0)throw e.validation("A media id is required.");return c}function Cn(c,u,w,p={}){let j=c.admin.auth,A=new Set(j?.methods??[]),S=c.uploads?.images,I=c.uploads?.retention,T=c.trash.purgeAfter,q=I?.purgeAfter??!1,O=c.uploads?.limits?.maxFileSize??null;return{title:c.admin.title??"Heyo CMS",basePath:c.basePath,panelPath:`${c.basePath}${c.admin.path}`,collections:Object.values(c.collections).map((J)=>st(J,u)),globals:Object.values(c.globals).map((J)=>st(J,u)),i18n:cr(c,w),media:{enabled:c.uploads!==void 0,variants:Object.keys(S?.variants?.sizes??{}),variantMode:S?.variants?.mode??null,focalPoint:S?.focalPoint===!0,crop:S?.crop===!0,accept:c.uploads?.limits?.accept??[],maxFileSize:O,maxFileSizeBytes:O===null?null:ee(O),purgeAfter:q===!1?null:q,purgeAfterMs:q===!1?null:b(q)},trash:{enabled:c.trash.enabled,purgeAfter:T===!1?null:T,purgeAfterMs:T===!1?null:b(T)},auth:{methods:[...A],twoFactor:j?.twoFactor===!0,apiKeys:j?.apiKeys?.enabled===!0,sso:j?.sso?.issuer??null,magicLink:A.has("magic-link")&&j?.deliverToken!==void 0,passwordReset:A.has("password")&&j?.deliverToken!==void 0,setupRequired:p.setupRequired===!0},rbac:{enabled:c.rbac!==void 0,roles:Object.keys(c.rbac?.roles??{}),customRoles:c.rbac?.customRoles===!0},ai:{configured:c.ai!==void 0,runtime:c.ai!==void 0,defaultModel:c.ai?.defaultModel??null,assistant:c.ai!==void 0&&c.ai.assistant?.enabled!==!1,assistantSettings:c.ai!==void 0&&c.ai.assistant?.enabled!==!1?{model:c.ai.assistant?.model??c.ai.defaultModel,maxTurns:c.ai.assistant?.maxTurns??se.maxTurns,maxToolCalls:c.ai.assistant?.maxToolCalls??se.maxToolCalls,timeoutMs:c.ai.assistant?.timeoutMs??se.timeoutMs,customInstructions:Boolean(c.ai.assistant?.instructions)}:null,actions:ce(),managedKeys:c.ai?.storage?.secret!==void 0},webhooks:{enabled:c.webhooks?.enabled===!0,managedInAdmin:c.webhooks?.managedInAdmin!==!1,runtime:c.webhooks?.enabled===!0,events:ir(c)},editor:de(),plugins:c.plugins.map((J)=>({id:J.id,navItems:J.admin?.navItems??[],scripts:J.admin?.scripts??[],fields:Object.keys(J.admin?.fields??{})}))}}function ir(c){if(c.webhooks?.enabled!==!0)return[];return["*","document.*","document.created","document.updated","document.field.changed","document.scheduled","document.schedule.applied","document.schedule.cancelled","document.trashed","document.restored","document.purged","media.*","media.uploaded","media.updated","media.orphaned","media.reclaimed","media.purged","ai.task.completed","ai.task.failed","ai.agent.completed","ai.agent.failed","ai.agent.mutation.applied","user.invited","user.joined","user.removed","role.changed","apikey.created","apikey.revoked","job.failed"]}function cr(c,u){return{locales:u.map((w)=>({code:w.code,name:w.name,rtl:w.rtl,isDefault:w.isDefault})),defaultLocale:c.i18n.defaultLocale}}function st(c,u){let w=Object.entries(c.fields).map(([p,j])=>lr(p,j,u));return{name:c.name,slug:c.slug,label:c.label,kind:c.kind,...c.admin?.group===void 0?{}:{group:c.admin.group},...c.admin?.description===void 0?{}:{description:c.admin.description},useAsTitle:dr(c),defaultColumns:c.admin?.defaultColumns??[],fields:w,can:{read:ie(c.access,"read",u),create:c.kind==="collection"&&ie(c.access,"create",u),update:ie(c.access,"update",u),delete:c.kind==="collection"&&ie(c.access,"delete",u)}}}function dr(c){let u=c.admin?.useAsTitle;if(u!==void 0&&c.fields[u])return u;for(let p of["title","name","label"])if(c.fields[p])return p;return Object.entries(c.fields).find(([,p])=>p.type==="text")?.[0]??null}function lr(c,u,w){let p=u.options,j=u.admin??{};return{name:c,type:u.type,label:typeof p.label==="string"?p.label:Re(c),...typeof p.description==="string"?{description:p.description}:{},required:u.required,localized:u.localized,readOnly:p.readOnly===!0,unique:p.unique===!0,generate:u.generate!==void 0,...u.defaultValue===void 0?{}:{defaultValue:u.defaultValue},options:pr(p),admin:{...typeof j.placeholder==="string"?{placeholder:j.placeholder}:{},hidden:j.hidden===!0},ai:ur(u),access:{read:ot(u.access?.read,w),update:p.readOnly===!0?!1:ot(u.access?.update,w)}}}function ur(c){let u={...c.ai??{},...c.aiGenerate===void 0?{}:{generate:c.aiGenerate}};return Object.entries(u).map(([w,p])=>({key:w,label:p===!0?Re(w):p.label??Re(w),...p===!0||p.model===void 0?{}:{model:p.model}}))}function pr(c){let u=new Set(["label","description","localized","required","unique","index","readOnly","ai","aiGenerate","generate","access","admin"]),w={};for(let[p,j]of Object.entries(c)){if(u.has(p))continue;let A=we(j);if(A!==void 0)w[p]=A}return w}function we(c){if(c===null)return null;switch(typeof c){case"string":case"boolean":return c;case"number":return Number.isFinite(c)?c:void 0;case"object":{if(Array.isArray(c))return c.map(we).filter((j)=>j!==void 0);let u=Object.entries(c),w={};for(let[p,j]of u){let A=we(j);if(A!==void 0)w[p]=A}return w}default:return}}function ie(c,u,w){let p=c[u];if(!p)return!0;try{let j=p({actor:w,operation:u,locale:null});if(j instanceof Promise)return!0;return j!==!1}catch{return!0}}function ot(c,u){if(!c)return!0;try{return c({actor:u,locale:null})}catch{return!0}}function Re(c){let u=c.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/[_-]+/g," ").trim();return u.charAt(0).toUpperCase()+u.slice(1)}function at(c){return[{method:"GET",path:"/panel",source:"core",handler:async(u)=>i(Cn(c._config,u.actor,c.locales.list(),{setupRequired:await mr(c)})),openapi:{summary:"What the panel renders",description:"Collections, fields, languages, media settings and what the caller may do, derived from the configuration. Public, because the sign-in screen is rendered from it; it contains no content and no credentials, and the per-actor flags are advisory — the engine decides every read and write.",tags:["admin"],security:!1,responses:{"200":r({type:"object"},"The panel's description of this deployment.")}}}]}async function mr(c){try{return await c.auth.setup.required()}catch{return!1}}function it(c){if(!c._config.trash.enabled)return[];let w=["trash"];return[{method:"GET",path:"/trash",source:"core",handler:async(p)=>{let j=p.query.get("collection"),A=R(p.query.get("limit"),"limit",1,200),S=p.query.get("cursor"),I=p.query.get("locale"),T=await c.trash.list({actor:p.actor,source:y(p.request),...j===null?{}:{collection:j},...A===void 0?{}:{limit:A},...S===null?{}:{cursor:S},...I===null?{}:{locale:I}});return i(T)},openapi:{summary:"List deleted documents",description:"Every collection at once, newest deletion first. A collection the caller may not read contributes nothing, so the list is shorter rather than forbidden.",tags:w,parameters:[a("collection","string","Restrict to one collection."),a("limit","integer","Page size. Defaults to 25."),a("cursor","string","Keyset cursor from the previous page."),a("locale","string","Language to resolve the documents in.")],responses:{"200":r({type:"object",properties:{entries:{type:"array",items:o("TrashedEntry")},limit:{type:"integer"},hasNextPage:{type:"boolean"},cursor:{type:["string","null"]}}},"One page of the bin.")}}},{method:"POST",path:"/trash/:collection/:id/restore",source:"core",handler:async(p)=>{let j=await c.trash.restore({collection:p.params.collection,id:p.params.id,actor:p.actor,source:y(p.request)});if(!j)throw e.notFound("Nothing was restored.");return i(j)},openapi:{summary:"Restore a document from the trash",tags:w,parameters:[l("collection","Collection name."),l("id","Document id.")],responses:{"200":r({type:"object"},"The restored document."),"409":r(o("Error"),"The document is not in the trash.")}}},{method:"DELETE",path:"/trash/:collection/:id",source:"core",handler:async(p)=>{let j=await c.trash.purge({collection:p.params.collection,id:p.params.id,actor:p.actor,source:y(p.request)});if(!j)throw e.notFound("Nothing was purged.");return i(j)},openapi:{summary:"Delete a document for good",description:"Needs the `purge` permission rather than `delete`: removing something and removing it so nobody can get it back are different decisions.",tags:w,parameters:[l("collection","Collection name."),l("id","Document id.")],responses:{"200":r({type:"object"},"The document as it last stood."),"403":r(o("Error"),"Access control refused the purge.")}}}]}function ct(c){let u=c._config;return[{method:"GET",path:"/locales",source:"core",handler:()=>i({locales:c.locales.list(),defaultLocale:u.i18n.defaultLocale}),openapi:{summary:"List the languages",description:"Anonymous, because a frontend needs the list to render a language switcher. The list is `i18n.locales` in the configuration; each entry carries the English name of its language and whether it is written right to left.",tags:["i18n"],security:!1,responses:{"200":r({type:"object",properties:{locales:{type:"array",items:o("Locale")},defaultLocale:{type:"string"}}},"The configured languages, and the one reads fall back to.")}}}]}function dt(c){let u=c._config;return[{method:"GET",path:"/activity",source:"core",handler:async(w)=>{m(u,w.actor,"activity:read");let p=w.query.get("collection"),j=w.query.get("documentId"),A=w.query.get("actorId"),S=w.query.get("action"),I=w.query.get("source"),T=w.query.get("cursor"),q=R(w.query.get("limit"),"limit",1,200),O=await c.activity.list({...p===null?{}:{collection:p},...j===null?{}:{documentId:j},...A===null?{}:{actorId:A},...S===null?{}:{action:S},...I===null?{}:{source:I},...T===null?{}:{cursor:T},...q===void 0?{}:{limit:q}});return i(O)},openapi:{summary:"Read the audit trail",description:"Written by the engine inside the transaction that caused each entry, so what is here committed and what is not here did not. Read-only: there is no way to delete a line.",tags:["activity"],parameters:[a("collection","string","Restrict to one collection."),a("documentId","string","Restrict to one document."),a("actorId","string","Restrict to one person or key."),a("action","string","`document.created`, `document.trashed`, …"),a("source","string","Where the write came from: `admin`, `rest`, `job`, `ai`."),a("limit","integer","Page size. Defaults to 50."),a("cursor","string","Keyset cursor from the previous page.")],responses:{"200":r({type:"object",properties:{entries:{type:"array",items:o("ActivityEntry")},limit:{type:"integer"},hasNextPage:{type:"boolean"},cursor:{type:["string","null"]}}},"One page of the trail.")}}}]}function lt(c){let u=c._config,w=["jobs"];return[{method:"POST",path:"/jobs/run",source:"core",handler:async(p)=>{m(u,p.actor,"jobs:run");let j=R(p.query.get("limit"),"limit",1,1000),A=p.query.getAll("only"),S=await c.jobs.run({...j===void 0?{}:{limit:j},...A.length===0?{}:{only:A}});return await c.drainEvents(),i(S)},openapi:{summary:"Run the due background work",description:`Registered sweeps: ${c.jobs.list().join(", ")||"none"}. Reports whether more was waiting than \`limit\` allowed, so a cron can loop instead of watching a backlog build.`,tags:w,parameters:[a("limit","integer","Items examined per job."),a("only","string","Run one job. Repeatable.")],responses:{"200":r(o("JobRunReport"),"What the sweep did."),"401":r(o("Error"),"Needs a session or an API key with `jobs:run`.")}}},{method:"GET",path:"/jobs/failures",source:"core",handler:async(p)=>{m(u,p.actor,"jobs:read");let j=p.query.get("type"),A=R(p.query.get("limit"),"limit",1,200),S=await c.jobs.failures({...j===null?{}:{type:j},...A===void 0?{}:{limit:A}});return i({failures:S})},openapi:{summary:"What failed",description:"Each row carries the payload. For a scheduled change that is the patch itself, and this row is the only remaining copy — the claim that removed it from the document had already happened when the write failed.",tags:w,parameters:[a("type","string","Job name."),a("limit","integer","Page size. Defaults to 50.")],responses:{"200":r({type:"object",properties:{failures:{type:"array",items:o("JobFailure")}}},"Recorded failures, newest first.")}}}]}function ht(c){let u=c._config;if(u.webhooks?.enabled!==!0)return[];let w=["webhooks"];return[{method:"GET",path:"/webhooks",source:"core",handler:async(p)=>{m(u,p.actor,"webhooks:read");let j=H(p.query.get("active"),"active"),A=await c.webhooks.list(j===void 0?{}:{active:j});return i({webhooks:A})},openapi:{summary:"List the subscriptions",description:"Secrets never leave: `hasSecret` says whether this subscription signs with its own, nothing says what it is.",tags:w,parameters:[a("active","boolean","Only active, or only inactive.")],responses:{"200":r({type:"object",properties:{webhooks:{type:"array",items:o("Webhook")}}},"Every subscription.")}}},{method:"POST",path:"/webhooks",source:"core",handler:async(p)=>{let j=m(u,p.actor,"webhooks:create"),A=await f(p.request),S=await c.webhooks.create({url:v(A,"url"),events:mt(A.events,"events"),...ke(A.filters)===void 0?{}:{filters:ke(A.filters)},...je(A.headers)===void 0?{}:{headers:je(A.headers)},...typeof A.secret==="string"?{secret:A.secret}:{},...typeof A.active==="boolean"?{active:A.active}:{},actor:j,source:y(p.request)});return i({webhook:S},201)},openapi:{summary:"Subscribe to events",description:"Event types may be exact (`document.updated`), a family (`document.*`) or everything (`*`). A family keeps working when the catalogue grows, which is why it exists.",tags:w,requestBody:h({type:"object",required:["url","events"],properties:{url:{type:"string",format:"uri"},events:{type:"array",items:{type:"string"}},filters:{type:"object",properties:{collections:{type:"array",items:{type:"string"}},locales:{type:"array",items:{type:"string"}}}},headers:{type:"object",additionalProperties:{type:"string"}},secret:{type:"string",description:"Overrides webhooks.signing.secret for this one."},active:{type:"boolean"}}}),responses:{"201":r({type:"object",properties:{webhook:o("Webhook")}},"The subscription."),"422":r(o("Error"),"The URL or the event list is not usable.")}}},{method:"PATCH",path:"/webhooks/:id",source:"core",handler:async(p)=>{let j=m(u,p.actor,"webhooks:update"),A=await f(p.request),S=await c.webhooks.update({id:p.params.id,...typeof A.url==="string"?{url:A.url}:{},...A.events===void 0?{}:{events:mt(A.events,"events")},...A.filters===void 0?{}:{filters:ke(A.filters)??{}},...A.headers===void 0?{}:{headers:je(A.headers)??{}},...typeof A.secret==="string"?{secret:A.secret}:{},...typeof A.active==="boolean"?{active:A.active}:{},actor:j,source:y(p.request)});return i({webhook:S})},openapi:{summary:"Change a subscription",tags:w,parameters:[l("id","Webhook id.")],requestBody:h({type:"object"}),responses:{"200":r({type:"object",properties:{webhook:o("Webhook")}},"The subscription."),"404":r(o("Error"),"No such webhook.")}}},{method:"DELETE",path:"/webhooks/:id",source:"core",handler:async(p)=>{let j=m(u,p.actor,"webhooks:delete");if(!await c.webhooks.remove({id:p.params.id,actor:j}))throw e.notFound("No such webhook.");return G()},openapi:{summary:"Unsubscribe",description:"The delivery history goes with it: it is the history of this subscription and means nothing without it.",tags:w,parameters:[l("id","Webhook id.")],responses:{"204":{description:"Removed."},"404":r(o("Error"),"No such webhook.")}}},{method:"GET",path:"/webhooks/deliveries",source:"core",handler:(p)=>ut(c,p),openapi:pt(!1)},{method:"GET",path:"/webhooks/:id/deliveries",source:"core",handler:(p)=>ut(c,p,p.params.id),openapi:pt(!0)},{method:"POST",path:"/webhooks/:id/test",source:"core",handler:async(p)=>{let j=m(u,p.actor,"webhooks:update"),A=await c.webhooks.test({id:p.params.id,actor:j});return i({delivery:A})},openapi:{summary:"Send a test event",description:"A real delivery carrying a synthetic `webhook.test` event: same signature, same headers, same retry rules. A receiver that accepts this accepts the real thing.",tags:w,parameters:[l("id","Webhook id.")],responses:{"200":r({type:"object",properties:{delivery:o("WebhookDelivery")}},"What the receiver answered.")}}},{method:"POST",path:"/webhooks/deliveries/:id/retry",source:"core",handler:async(p)=>{let j=m(u,p.actor,"webhooks:update"),A=await c.webhooks.retry({id:p.params.id,actor:j});return i({delivery:A})},openapi:{summary:"Replay a delivery",description:"A new attempt carrying the same event id, so a consumer's idempotency key still matches and the original attempt stays readable.",tags:w,parameters:[l("id","Delivery id.")],responses:{"200":r({type:"object",properties:{delivery:o("WebhookDelivery")}},"The replayed delivery."),"404":r(o("Error"),"No such delivery.")}}}]}async function ut(c,u,w){m(c._config,u.actor,"webhooks:read");let p=u.query.get("status"),j=u.query.get("eventId"),A=u.query.get("cursor"),S=R(u.query.get("limit"),"limit",1,200),I=H(u.query.get("includeBody"),"includeBody"),T=await c.webhooks.deliveries({...w===void 0?{}:{webhookId:w},...p===null?{}:{status:p},...j===null?{}:{eventId:j},...A===null?{}:{cursor:A},...S===void 0?{}:{limit:S},...I===void 0?{}:{includeBody:I}});return i(T)}function pt(c){return{summary:c?"Deliveries for one subscription":"Every delivery",description:"Newest first. `failed` is the dead-letter queue: out of attempts, still here, replayable.",tags:["webhooks"],parameters:[...c?[l("id","Webhook id.")]:[],a("status","string","pending, delivered or failed."),a("eventId","string","Every attempt at one event."),a("limit","integer","Page size. Defaults to 25."),a("cursor","string","Keyset cursor from the previous page."),a("includeBody","boolean","Includes the signed request body.")],responses:{"200":r({type:"object",properties:{entries:{type:"array",items:o("WebhookDelivery")},limit:{type:"integer"},hasNextPage:{type:"boolean"},cursor:{type:["string","null"]}}},"One page of deliveries.")}}}function mt(c,u){if(!Array.isArray(c))throw e.validation(`"${u}" has to be an array of strings.`);return c.filter((w)=>typeof w==="string")}function ke(c){if(typeof c!=="object"||c===null)return;let u=c,w=Array.isArray(u.collections)?u.collections.filter((j)=>typeof j==="string"):void 0,p=Array.isArray(u.locales)?u.locales.filter((j)=>typeof j==="string"):void 0;return{...w===void 0?{}:{collections:w},...p===void 0?{}:{locales:p}}}function je(c){if(typeof c!=="object"||c===null)return;let u={};for(let[w,p]of Object.entries(c))if(typeof p==="string")u[w]=p;return u}function Pe(c){let u=c._config,w=u.basePath,p=new _e,j,A=()=>(j??=kn(c,p.list()),j);for(let q of gr(c))p.add(q);for(let q of u.plugins)for(let O of q.routes??[])p.add(br(q.id,O));p.add(ze(A));let S=ft(u.hooks?.before??[]),I=ft(u.hooks?.after??[]);return{handler:async(q)=>{let O=new URL(q.url),J=vr(O.pathname,w);if(J===null)return i({error:{message:`This handler serves ${w}; the request was for ${O.pathname}.`,code:"outside_base_path",status:404}},404);let x=null,D={},L;try{Rr(q),x=await wr(c,q);let W={request:q,path:J,method:q.method,headers:q.headers,actor:x,cms:c,meta:D};for(let Z of S){if(!Z.matcher(W))continue;let U=await Z.handler(W);if(U instanceof Response){L=U;break}}L??=await hr({cms:c,router:p,request:q,url:O,path:J,actor:x,meta:D})}catch(W){L=Gt(W)}if(I.length===0)return L;return yr({after:I,cms:c,request:q,path:J,actor:x,meta:D,response:L})},routes:()=>p.routes(w),openapi:A}}async function hr(c){let{cms:u,router:w,request:p,url:j,path:A,actor:S,meta:I}=c,T=w.match(p.method,A);if(T.kind==="method-not-allowed")return i({error:{message:`${p.method} is not allowed on ${A}.`,code:"method_not_allowed",status:405}},405,{allow:[...T.allowed,"OPTIONS"].join(", ")});if(T.kind==="not-found"){if(p.method==="OPTIONS")return new Response(null,{status:204,headers:{allow:"OPTIONS"}});return i({error:{message:`No route for ${p.method} ${A}.`,code:"not_found",status:404}},404)}let q={request:p,params:T.params,query:j.searchParams,actor:S,cms:u,db:Rn(()=>u.database()),database:()=>u.database(),body:()=>Kt(p),meta:I,json:(J,x)=>i(J,x),text:(J,x)=>An(J,x)},O=await fr(T.route,q);if(p.method==="HEAD")return new Response(null,{status:O.status,statusText:O.statusText,headers:O.headers});return O}function fr(c,u){let w=c.middleware??[],p=-1,j=async()=>{p+=1;let A=w[p];if(!A)return c.handler(u);return A(u,j)};return j()}async function yr(c){let{after:u,cms:w,request:p,path:j,actor:A,meta:S,response:I}=c,T=new Headers(I.headers),q={request:p,path:j,method:p.method,headers:T,status:I.status,actor:A,cms:w,meta:S};try{for(let O of u){if(!O.matcher(q))continue;let J=await O.handler(q);if(J instanceof Response)return J}}catch(O){return Gt(O)}return new Response(I.body,{status:I.status,statusText:I.statusText,headers:T})}function gr(c){return[...xe(c),...De(c),...rt(c),...nt(c),...Ke(c),...Qe(c),...ht(c),...tt(c),...Be(c),...ct(c),...it(c),...dt(c),...lt(c),...at(c),...We(c)]}function br(c,u){return{method:u.method,path:u.path,source:c,handler:u.handler,...u.middleware===void 0?{}:{middleware:u.middleware},...u.openapi===void 0?{}:{openapi:u.openapi}}}async function wr(c,u){try{return await c.auth.actorFromRequest(u)}catch(w){if(w instanceof e&&w.status===401)return null;throw w}}function vr(c,u){if(u==="/")return c;if(!c.startsWith(u))return null;let w=c.slice(u.length);if(w.length===0)return"/";if(!w.startsWith("/"))return null;return w}function Rr(c){if(["GET","HEAD","OPTIONS"].includes(c.method))return;if(/^Bearer\s+\S+/i.test(c.headers.get("authorization")??""))return;let u=c.headers.get("origin");if(u!==null&&u!==new URL(c.url).origin||c.headers.get("sec-fetch-site")==="cross-site")throw e.forbidden("Cross-origin browser writes are not allowed.")}function ft(c){return[...c].map((u,w)=>({hook:u,index:w})).sort((u,w)=>(u.hook.priority??100)-(w.hook.priority??100)||u.index-w.index).map((u)=>u.hook)}
|
|
40
|
-
export{Fe,m,Je,y,E,vn,Kn,Yn,R,H,i,An,G,B,Gt,Kt,f,Oe,v,F,ve,o,l,a,K,xn,h,r,M,yt,kn,Rn,_e,Zn,Cn,Pe};
|
package/dist/index-ty698y02.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{de}from"./index-9zqnf6gx.js";import{z,ce,C,Yt,le,_}from"./index-vq2978e7.js";import{Re,S,A,Ce,Ie,ao,co,Te,sn,c,p}from"./index-2z1qe5mw.js";import{s,k,t,U,j,I,oe,u}from"./index-vxw0a03g.js";import{Zn,Pe}from"./index-nvgwyykk.js";import{Ut,Wt,Ht,W,q,Bt,zt}from"./index-wj8y1xcj.js";import{ht}from"./index-hq05mc1n.js";import{be,we}from"./index-7k091gpe.js";import{d}from"./index-9g2n7xa6.js";import{me,He,Be}from"./index-2757kej5.js";import{g,At}from"./index-ymq6jsar.js";import{Ve}from"./index-y5mwknr9.js";import{tn}from"./index-5ngtc7gy.js";import{b,ee}from"./index-cbwwtcm4.js";import{O}from"./index-m82a0shw.js";import{w,ge}from"./index-2kb5nbxx.js";import{e,n}from"./index-x72d1hzh.js";var Ne="activity",Ge=50,ze=200;function Ae(o){return{async list(i={}){let a=Ue(i.limit),r=[];if(i.collection)r.push(t("collection",i.collection));if(i.documentId)r.push(t("document_id",i.documentId));if(i.actorId)r.push(t("actor_id",i.actorId));if(i.action)r.push(t("action",i.action));if(i.source)r.push(t("source",i.source));if(i.cursor)r.push(U("id",i.cursor));let l=await o.database(),f=await l.transaction((v)=>l.query(v,{table:Ne,...r.length===0?{}:{where:s(...r)},orderBy:[{path:"id",direction:"desc"}],limit:a+1})),h=f.length>a,m=f.slice(0,a),R=m.at(-1);return{entries:m.map(qe),limit:a,hasNextPage:h,cursor:h&&R?String(R.id):null}}}}function qe(o){let i=o.changes===null||o.changes===void 0?null:p(o.changes);return{id:String(o.id),action:String(o.action),actorId:Y(o.actor_id),actorSource:Y(o.actor_source),source:Y(o.source),collection:Y(o.collection),documentId:Y(o.document_id),locale:Y(o.locale),changes:i,ip:Y(o.ip),createdAt:c(o.created_at)}}function Y(o){return o===null||o===void 0?null:String(o)}function Ue(o){if(o===void 0)return Ge;if(!Number.isInteger(o)||o<1)throw new e(`limit must be a positive integer, received ${o}`,{status:400,code:"invalid_pagination"});return Math.min(o,ze)}function Xe(o,i){let a={createBefore:[],createAfter:[],updateBefore:[],updateAfter:[],deleteBefore:[],deleteAfter:[]},r=o.plugins.flatMap((f)=>(f.hooks??[]).filter((h)=>h.collection===i).map((h)=>({plugin:f.id,hook:h}))).sort((f,h)=>(f.hook.priority??0)-(h.hook.priority??0)||f.plugin.localeCompare(h.plugin));for(let{plugin:f,hook:h}of r){let m={source:f,priority:h.priority??0};if(h.timing==="before"){if(h.operation==="create")a.createBefore.push({...m,run:(v,D)=>h.handler(v.data,D)});else if(h.operation==="update")a.updateBefore.push({...m,run:(v,D)=>h.handler(v.data,D)});else a.deleteBefore.push({...m,run:(v,D)=>h.handler(v,D)});continue}let R=async(v,D)=>{await h.handler(v,D)};if(h.operation==="create")a.createAfter.push({...m,run:R});else if(h.operation==="update")a.updateAfter.push({...m,run:(v,D)=>R(v.doc,D)});else a.deleteAfter.push({...m,run:R})}let l=o.pluginHooks.filter((f)=>f.collection===i).sort((f,h)=>f.priority-h.priority||f.plugin.localeCompare(h.plugin));for(let f of l)_e(a,f.hooks,{source:f.plugin,priority:f.priority});return _e(a,o.databaseHooks?.[i],{source:"config",priority:Ke}),a}var Ke=100;function _e(o,i,a){if(i?.create?.before){let r=i.create.before;o.createBefore.push({...a,run:(l,f)=>r(l,f)})}if(i?.create?.after){let r=i.create.after;o.createAfter.push({...a,run:(l,f)=>r(l,f)})}if(i?.update?.before){let r=i.update.before;o.updateBefore.push({...a,run:async(l,f)=>await r(l,f)})}if(i?.update?.after){let r=i.update.after;o.updateAfter.push({...a,run:(l,f)=>r(l,f)})}if(i?.delete?.before){let r=i.delete.before;o.deleteBefore.push({...a,run:(l,f)=>r(l,f)})}if(i?.delete?.after){let r=i.delete.after;o.deleteAfter.push({...a,run:(l,f)=>r(l,f)})}}async function Se(o,i,a,r){let l=i;for(let f of o){let h=await f.run(l,a);if(h===!1)return!1;if(h&&typeof h==="object"&&"data"in h)l=r(l,h.data)}return l}async function De(o,i,a){for(let r of o)await r.run(i,a)}function Dt(o){let i=new Set([...Object.keys(o.collections),...Object.keys(o.globals),...o.plugins.flatMap((r)=>(r.hooks??[]).map((l)=>l.collection)),...o.pluginHooks.map((r)=>r.collection)]),a=[];for(let r of[...i].sort()){let l=Xe(o,r),f=[["create","before",l.createBefore],["create","after",l.createAfter],["delete","before",l.deleteBefore],["delete","after",l.deleteAfter],["update","before",l.updateBefore],["update","after",l.updateAfter]];for(let[h,m,R]of f)for(let v of R)a.push({collection:r,operation:h,timing:m,source:v.source,priority:v.priority})}return a}var Ze="jobs",Qe=100,Ye={name:"scheduled-changes",failureType:"document.schedule",failurePayload:(o)=>{let i=Te(o);return{collection:String(o.collection),documentId:String(o.id),...i===null?{}:{locale:i.locale,patch:i.data},...o.scheduled_at instanceof Date?{scheduledFor:o.scheduled_at.toISOString()}:{}}},due:async(o,i,a)=>{let r=await o.database();return r.transaction((l)=>r.query(l,{table:g,where:s(oe("scheduled_at",!0),j("scheduled_at",i),t("deleted_at",null)),orderBy:[u("scheduled_at","asc"),u("id","asc")],limit:a}))},run:(o,i)=>o.applyScheduled(i)},st={name:"trash-purge",failureType:"trash.purge",failurePayload:(o)=>({collection:String(o.collection),documentId:String(o.id)}),due:async(o,i,a)=>{if(o.config.trash.purgeAfter===!1)return[];let r=await o.database();return r.transaction((l)=>r.query(l,{table:g,where:s(oe("deleted_at",!0),oe("purge_after",!0),j("purge_after",i)),orderBy:[u("purge_after","asc"),u("id","asc")],limit:a}))},run:(o,i)=>o.purgeExpired(i)};class et{host;jobs=[Ye,st];constructor(o){this.host=o}list(){return this.jobs.map((o)=>o.name)}register(o){this.jobs.push(o)}async run(o={}){let i=o.now??new Date,a=o.limit??Qe,r=o.only?this.jobs.filter((f)=>o.only?.includes(f.name)):this.jobs,l=[];for(let f of r){let h=await f.due(this.host,i,a+1),m=h.slice(0,a),R=0,v=0;for(let D of m)try{await f.run(this.host,D,i),R+=1}catch(B){v+=1,await this.host.recordFailure(f.failureType,f.failurePayload(D),B).catch(()=>{return})}l.push({job:f.name,processed:R,failed:v,more:h.length>a})}return{ranAt:i.toISOString(),processed:l.reduce((f,h)=>f+h.processed,0),failed:l.reduce((f,h)=>f+h.failed,0),results:l}}async failures(o={}){let i=await this.host.database();return(await i.transaction((r)=>i.query(r,{table:Ze,where:o.type===void 0?t("status","failed"):s(t("status","failed"),t("type",o.type)),orderBy:[u("created_at","desc"),u("id","desc")],limit:o.limit??50}))).map((r)=>({id:String(r.id),type:String(r.type),payload:r.payload===null||r.payload===void 0?null:p(r.payload),error:r.error===null||r.error===void 0?null:String(r.error),attempts:Number(r.attempts??0),createdAt:c(r.created_at)}))}}var ne="outbox";class tt{queued=[];emit(o,i,a=null){this.queued.push({type:o,data:i,previous:a})}take(){return this.queued.splice(0,this.queued.length)}}class nt{adapter;dispatch;maxAttempts;backoff;leaseMs;now;constructor(o,i,a={}){this.adapter=o;this.dispatch=i;this.maxAttempts=a.maxAttempts??5,this.backoff=a.backoff??((r)=>1000*2**(r-1)),this.leaseMs=a.leaseMs??300000,this.now=a.now??(()=>new Date)}async append(o,i,a){let r=this.now();for(let l of i)await this.adapter.mutate(o,{kind:"insert",table:ne,returning:!1,values:{id:ge("obx"),event_id:w("evt"),type:l.type,payload:l.data,previous:l.previous,actor:a.actor?{id:a.actor.id,source:a.actor.source}:null,collection:a.collection??null,document_id:a.documentId??null,status:"pending",attempts:0,available_at:r,processed_at:null,error:null,created_at:r}})}async drain(o=50){let i=await this.adapter.transaction((r)=>this.adapter.query(r,{table:ne,where:s(I("status",["pending","delivering"]),j("available_at",this.now())),orderBy:[u("created_at","asc"),u("id","asc")],limit:o})),a=0;for(let r of i){if(await this.hasPredecessor(r))continue;let l=await this.claim(r);if(!l)continue;if(Number(l.attempts)>this.maxAttempts){await this.settle(l,!1,Error("Delivery lease expired; attempt budget exhausted."));continue}try{await this.dispatch(at(l)),await this.settle(l,!0),a+=1}catch(f){await this.settle(l,!1,f)}}return a}async hasPredecessor(o){if(!o.document_id)return!1;return(await this.adapter.transaction((a)=>this.adapter.query(a,{table:ne,where:s(t("collection",o.collection==null?null:String(o.collection)),t("document_id",String(o.document_id)),U("id",String(o.id)),I("status",["pending","delivering"])),limit:1}))).length>0}async claim(o){let i={status:"delivering",attempts:Number(o.attempts??0)+1,available_at:new Date(this.now().getTime()+this.leaseMs)};return(await this.adapter.transaction((r)=>this.adapter.mutate(r,{kind:"update",table:ne,where:s(t("id",String(o.id)),t("status",String(o.status)),t("attempts",Number(o.attempts??0)),j("available_at",this.now())),set:i,returning:!1}))).count===1?{...o,...i}:null}async settle(o,i,a){let r=Number(o.attempts??0),l=r>=this.maxAttempts,f=i?{status:"delivered",attempts:r,processed_at:this.now(),error:null}:{status:l?"failed":"pending",attempts:r,available_at:new Date(this.now().getTime()+this.backoff(r)),error:a instanceof Error?a.message:String(a)};await this.adapter.transaction((h)=>this.adapter.mutate(h,{kind:"update",table:ne,where:s(t("id",String(o.id)),t("status","delivering"),t("attempts",r)),set:f,returning:!1}))}}function at(o){let i=p(o.actor);return{id:String(o.event_id),type:String(o.type),createdAt:c(o.created_at)??new Date().toISOString(),actor:typeof i.id==="string"?{id:i.id,source:i.source==="api-key"?"api-key":"session"}:null,data:p(o.payload),previous:o.previous===null||o.previous===void 0?null:p(o.previous)}}class ot{options;cache=new Map;queries=0;constructor(o){this.options=o}get queryCount(){return this.queries}async expand(o,i,a){if(a<=0||o.length===0)return;let r=Object.entries(i.fields).map(([h,m])=>({name:h,target:un(m)})).filter((h)=>Boolean(h.target));if(r.length===0)return;let l=new Map;for(let h of o)for(let m of r)for(let R of lt(h[m.name])){if(this.cache.has(X(m.target,R)))continue;let v=l.get(m.target)??new Set;v.add(R),l.set(m.target,v)}for(let[h,m]of l)await this.load(h,[...m]);let f=new Map;for(let h of o)for(let m of r){let R=h[m.name];h[m.name]=this.substitute(m.target,R,f)}for(let[h,m]of f){let R=this.options.collections[h];if(R)await this.expand(m,R,a-1)}}async load(o,i){let a=this.options.collections[o];if(this.queries+=1,a){for(let m of i)this.cache.set(X(o,m),null);let l;try{l=await C(a,{actor:this.options.actor??null,operation:"read",locale:this.options.locale.locale,rbac:this.options.rbac})}catch(m){if(m instanceof e&&(m.status===401||m.status===403))return;throw m}let f=[l,t("collection",a.slug),I("id",i),...this.options.includeTrashed?[]:[t("deleted_at",null)]],h=await this.options.adapter.query(this.options.tx,{table:g,where:s(...f)});for(let m of i)this.cache.set(X(o,m),null);for(let m of h){let R=A(m,a,this.options.locale);this.cache.set(X(o,String(m.id)),le(R,a,this.options.actor??null,this.options.locale.locale))}return}for(let l of i)this.cache.set(X(o,l),null);if(o!=="media"&&o!=="cms_users")return;let r=await this.options.adapter.query(this.options.tx,{table:o,where:I("id",i),...o==="cms_users"?{select:["id","name"]}:{}});for(let l of i)this.cache.set(X(o,l),null);for(let l of r)this.cache.set(X(o,String(l.id)),co(l))}substitute(o,i,a){let r=(l)=>{let f=structuredClone(l),h=a.get(o)??[];return h.push(f),a.set(o,h),f};if(typeof i==="string"){let l=this.cache.get(X(o,i));return l?r(l):i}if(Array.isArray(i))return i.map((l)=>{if(typeof l!=="string")return l;let f=this.cache.get(X(o,l));return f?r(f):l});return i??null}}function un(o){if(o.relationTo)return o.relationTo;return o.type==="media"?"media":void 0}function lt(o){if(typeof o==="string")return o.length>0?[o]:[];if(Array.isArray(o))return o.filter((i)=>typeof i==="string");return[]}function X(o,i){return`${o}:${i}`}var ct=25,dt=200,fe=[u("deleted_at","desc"),u("id","desc")];async function Mt(o){let{adapter:i,config:a,collections:r,args:l}=o,f=S(a,l),h=l.actor??null,m=pt(l.limit),R=l.collection?[ut(r,l.collection)]:Object.values(r),v=[],D=new Map;for(let x of R){let P;try{P=await C(x,{actor:h,operation:"read",locale:f.locale,rbac:a.rbac})}catch(L){if(l.collection)throw L;continue}D.set(x.slug,x),v.push(P?s(t("collection",x.slug),P):t("collection",x.slug))}if(v.length===0)return{entries:[],limit:m,hasNextPage:!1,cursor:null};let B=v.length===D.size&&v.every((x)=>x.kind==="compare")?I("collection",[...D.keys()]):k(...v),H=s(oe("deleted_at",!0),B),M=await i.transaction((x)=>i.query(x,{table:g,where:l.cursor?s(H,q(l.cursor,fe)):H,orderBy:fe,limit:m+1})),y=M.length>m,T=M.slice(0,m),J=T.flatMap((x)=>{let P=D.get(String(x.collection));if(!P)return[];let L=A(x,P,f);if(Yt(P))le(L,P,h,f.locale);return[{collection:P.name,id:String(x.id),deletedAt:c(x.deleted_at),purgeAfter:c(x.purge_after),document:L}]}),E=T.at(-1);return{entries:J,limit:m,hasNextPage:y,cursor:E?W(E,fe):null}}function ut(o,i){let a=o[i];if(!a)throw e.notFound(`No collection named "${i}"`);return a}function pt(o){if(o===void 0)return ct;if(!Number.isInteger(o)||o<1)throw new e(`limit must be a positive integer, received ${o}`,{status:400,code:"invalid_pagination"});return Math.min(o,dt)}var ft=25,mt=500,bt="activity",yt="media_usages",Oe="cms_ai_mutations",xe={create:"create",update:"update",trash:"delete",purge:"delete",restore:"update",schedule:"update",unschedule:"update"};class rt{options;cms;pipelines=new Map;byName;bySlug;media=new Map;outbox;delivery=Promise.resolve();constructor(o){this.options=o;this.byName={...o.config.collections,...o.config.globals},this.bySlug=Object.fromEntries(Object.values(this.byName).map((i)=>[i.slug,i]))}bind(o){this.cms=o}buildApi(){let o={};for(let i of Object.values(this.options.config.collections))o[i.name]=this.collectionApi(i);return o}buildGlobals(){let o={};for(let i of Object.values(this.options.config.globals))o[i.name]=this.globalApi(i);return o}buildTrash(){return{list:async(o={})=>{let i=await this.options.database();return Mt({adapter:i,config:this.options.config,collections:this.byName,args:o})},restore:(o)=>this.restore(this.requireCollection(o.collection),{...o,id:o.id}),purge:(o)=>this.purge(this.requireCollection(o.collection),{...o,id:o.id})}}buildJobs(){return new et({config:this.options.config,database:()=>this.options.database(),applyScheduled:(o)=>this.applyScheduled(o),purgeExpired:(o)=>this.purgeExpired(o),recordFailure:(o,i,a)=>this.recordFailure(o,i,a)})}async drainEvents(o){return await this.delivery,(await this.outboxWorker()).drain(o)}async settle(){await this.delivery}async appendEvents(o,i,a){await(await this.outboxWorker()).append(o,i,a)}deliverSoon(){this.scheduleDelivery()}collectionApi(o){return{find:(i)=>this.find(o,i),findOne:(i)=>this.findOne(o,i),findById:(i,a)=>this.findById(o,i,a),count:(i)=>this.count(o,i),create:(i)=>this.create(o,i),update:(i)=>this.update(o,i),delete:(i)=>this.remove(o,i),restore:(i)=>this.restore(o,i),purge:(i)=>this.purge(o,i),schedule:(i)=>this.schedule(o,i),unschedule:(i)=>this.unschedule(o,i)}}async find(o,i={}){let a=await this.options.database(),r=S(this.options.config,i),l=i.actor??null,f=await C(o,{actor:l,operation:"read",locale:r.locale,rbac:this.options.config.rbac}),h=this.scope(o,i.where,f,i.includeTrashed),m=gt(i.orderBy),R=wt(i.limit);return a.transaction(async(v)=>{let D=await a.query(v,{table:g,where:i.cursor?s(h,q(i.cursor,m)):h,orderBy:m,limit:R+1,...i.offset===void 0?{}:{offset:i.offset}}),B=D.length>R,H=D.slice(0,R),M=H.map((J)=>A(J,o,r));await this.expand(a,v,M,o,r,i,l),this.redact(M,o,l,r);let y=null;if(i.count===!0){let J=await a.query(v,{table:g,where:h,count:!0});y=Number(J[0]?.count??0)}let T=H.at(-1);return{docs:M,limit:R,totalDocs:y,hasNextPage:B,cursor:T?W(T,m):null}})}async findOne(o,i={}){return(await this.find(o,{...i,limit:1})).docs[0]??null}async findById(o,i,a={}){return this.findOne(o,{...a,where:t("id",i)})}async count(o,i={}){let a=await this.options.database(),r=S(this.options.config,i),l=await C(o,{actor:i.actor??null,operation:"read",locale:r.locale,rbac:this.options.config.rbac}),f=this.scope(o,i.where,l,i.includeTrashed);return a.transaction(async(h)=>{let m=await a.query(h,{table:g,where:f,count:!0});return Number(m[0]?.count??0)})}async create(o,i){let a=S(this.options.config,i),r=i.actor??null,l={...i.data};return this.runWrite({collection:o,intent:"create",actor:r,source:i.source??"local",locale:a,depth:i.depth,includeTrashed:i.includeTrashed,runId:i.runId,idempotencyKey:i.idempotencyKey,step:async({db:f,hooks:h,context:m})=>{await this.assertAllowed(o,"create",r,a),_(o,l,r,a.locale);let R=await Se(h.createBefore,{data:l},m,(M,y)=>({...M,data:y}));if(R===!1)return null;let{data:v,touched:D}=Ce(o,R.data,a);Ie(o,v,a,Object.keys(o.fields));let B=new Date,H=await f.insert(g,{id:i.id??w("doc"),collection:o.slug,data:v,created_at:B,updated_at:B,updated_by:r?.id??null,deleted_at:null,purge_after:null,scheduled_at:null,scheduled_patch:null,revision:1});return{doc:A(H,o,a),previous:null,changed:D,stored:v}}})}async update(o,i,a){let r=S(this.options.config,i),l=i.actor??null,f={...i.data};return this.runWrite({collection:o,intent:"update",actor:l,source:i.source??"local",locale:r,depth:i.depth,includeTrashed:i.includeTrashed,runId:i.runId,idempotencyKey:i.idempotencyKey,...a===void 0?{}:{emit:a},step:async({adapter:h,tx:m,hooks:R,context:v})=>{let D=await this.load(h,m,o,i.id,{actor:l,operation:"update",locale:r,includeTrashed:i.includeTrashed});he(i.expectedRevision,D);let B=A(D,o,r);await this.assertAllowed(o,"update",l,r,B),_(o,f,l,r.locale,B);let H=await Se(R.updateBefore,{data:f,previous:B},v,(x,P)=>({...x,data:P}));if(H===!1)return null;let{data:M,touched:y}=Ce(o,H.data,r,p(D.data));Ie(o,M,r,y);let T=new Date,J=await this.patch(h,m,D,{data:M,updated_at:T,updated_by:l?.id??null},i.expectedRevision),E=A(J,o,r);return{doc:E,previous:B,changed:ao(o,B,E),stored:M}}})}async remove(o,i){if(!this.options.config.trash.enabled||i.permanent===!0)return this.purge(o,i);let r=S(this.options.config,i),l=i.actor??null;return this.runWrite({collection:o,intent:"trash",actor:l,source:i.source??"local",locale:r,depth:i.depth,includeTrashed:!0,runId:i.runId,idempotencyKey:i.idempotencyKey,step:async({adapter:f,tx:h,hooks:m,context:R})=>{let v=await this.load(f,h,o,i.id,{actor:l,operation:"delete",locale:r,includeTrashed:!1});he(i.expectedRevision,v);let D=A(v,o,r);await this.assertAllowed(o,"delete",l,r,D);let B=await Se(m.deleteBefore,D,R,(y,T)=>T);if(B===!1)return null;let H=new Date,M=await this.patch(f,h,v,{deleted_at:H,purge_after:this.purgeAt(H),scheduled_at:null,scheduled_patch:null,updated_at:H,updated_by:l?.id??null});return{doc:A(M,o,r),previous:B,changed:[]}}})}async restore(o,i){let a=S(this.options.config,i),r=i.actor??null;return this.runWrite({collection:o,intent:"restore",actor:r,source:i.source??"local",locale:a,depth:i.depth,includeTrashed:!0,runId:i.runId,idempotencyKey:i.idempotencyKey,step:async({adapter:l,tx:f})=>{let h=await this.load(l,f,o,i.id,{actor:r,operation:"restore",locale:a,includeTrashed:!0});if(he(i.expectedRevision,h),h.deleted_at===null||h.deleted_at===void 0)throw e.conflict(`${o.name} "${i.id}" is not in the trash`);let m=A(h,o,a);await this.assertAllowed(o,"restore",r,a,m);let R=new Date,v=await this.patch(l,f,h,{deleted_at:null,purge_after:null,updated_at:R,updated_by:r?.id??null});return{doc:A(v,o,a),previous:m,changed:[],after:!1}}})}async purge(o,i,a={}){let r=S(this.options.config,i),l=i.actor??null;return this.runWrite({collection:o,intent:"purge",actor:l,source:i.source??"local",locale:r,depth:i.depth,includeTrashed:!0,step:async({adapter:f,tx:h,db:m,hooks:R,context:v})=>{let D=await this.load(f,h,o,i.id,{actor:l,operation:"purge",locale:r,includeTrashed:!0,bypassAccess:a.retention===!0}),B=A(D,o,r),H=D.deleted_at!==null&&D.deleted_at!==void 0;if(a.retention!==!0)await this.assertAllowed(o,H?"purge":"delete",l,r,B);let M=H?B:await Se(R.deleteBefore,B,v,(y,T)=>T);if(M===!1)return null;return await m.delete(g,t("id",String(D.id))),{doc:M,previous:M,changed:[],after:!H,releaseMedia:!0}}})}async schedule(o,i){let a=S(this.options.config,i),r=i.actor??null,l=vt(i.at),f={...i.data};if(Object.keys(f).length===0)throw e.validation("A scheduled change needs at least one field.");return this.runWrite({collection:o,intent:"schedule",actor:r,source:i.source??"local",locale:a,depth:i.depth,includeTrashed:!1,step:async({adapter:h,tx:m})=>{let R=await this.load(h,m,o,i.id,{actor:r,operation:"update",locale:a,includeTrashed:!1}),v=A(R,o,a);await this.assertAllowed(o,"update",r,a,v),_(o,f,r,a.locale,v);let D=Ce(o,f,a,p(R.data));Ie(o,D.data,a,D.touched);let B=new Date,H=await this.patch(h,m,R,{scheduled_at:l,scheduled_patch:{data:f,locale:a.locale,actor:r===null?null:{...r}},updated_at:B,updated_by:r?.id??null});return{doc:A(H,o,a),previous:v,changed:[],after:!1}}})}async unschedule(o,i){let a=S(this.options.config,i),r=i.actor??null;return this.runWrite({collection:o,intent:"unschedule",actor:r,source:i.source??"local",locale:a,depth:i.depth,includeTrashed:!1,step:async({adapter:l,tx:f})=>{let h=await this.load(l,f,o,i.id,{actor:r,operation:"update",locale:a,includeTrashed:!1});if(h.scheduled_at===null||h.scheduled_at===void 0)throw e.conflict(`${o.name} "${i.id}" has nothing scheduled`);let m=A(h,o,a);await this.assertAllowed(o,"update",r,a,m);let R=new Date,v=await this.patch(l,f,h,{scheduled_at:null,scheduled_patch:null,updated_at:R,updated_by:r?.id??null});return{doc:A(v,o,a),previous:m,changed:[],after:!1}}})}globalApi(o){return{get:(i)=>this.globalGet(o,i),update:async(i)=>{let a=await this.ensureGlobalRow(o,i);return this.update(o,{...i,id:a})},schedule:async(i)=>{let a=await this.ensureGlobalRow(o,i);return this.schedule(o,{...i,id:a})},unschedule:async(i={})=>this.unschedule(o,{...i,id:V(o)})}}async globalGet(o,i={}){let a=await this.options.database(),r=S(this.options.config,i),l=i.actor??null,f=await C(o,{actor:l,operation:"read",locale:r.locale,rbac:this.options.config.rbac});return a.transaction(async(h)=>{let R=(await a.query(h,{table:g,where:this.scope(o,t("id",V(o)),f,!1),limit:1}))[0]??this.emptyGlobalRow(o,r,null),v=A(R,o,r);return await this.expand(a,h,[v],o,r,i,l),this.redact([v],o,l,r),v})}async ensureGlobalRow(o,i){let a=await this.options.database(),r=S(this.options.config,i),l=V(o);if(await a.transaction(async(h)=>(await a.query(h,{table:g,where:t("id",l),limit:1})).length>0))return l;try{await a.transaction((h)=>a.mutate(h,{kind:"insert",table:g,returning:!1,values:this.emptyGlobalRow(o,r,new Date)}))}catch(h){if(!await a.transaction(async(R)=>(await a.query(R,{table:g,where:t("id",l),limit:1})).length>0))throw h}return l}emptyGlobalRow(o,i,a){let{data:r}=Ce(o,{},i);return{id:V(o),collection:o.slug,data:r,created_at:a,updated_at:a,updated_by:null,deleted_at:null,purge_after:null,scheduled_at:null,scheduled_patch:null,revision:1}}async applyScheduled(o){let i=this.bySlug[String(o.collection)],a=Te(o),r=o.scheduled_at;if(!i||!a||!(r instanceof Date)){await this.clearSchedule(String(o.id));return}let l=await this.options.database();if((await l.transaction((h)=>l.mutate(h,{kind:"update",table:g,where:s(t("id",String(o.id)),t("scheduled_at",r)),set:{scheduled_at:null,scheduled_patch:null},returning:!1}))).count!==1)return;await this.update(i,{id:String(o.id),data:a.data,locale:a.locale,actor:a.actor,source:"job"},(h,m)=>{h.emit("document.schedule.applied",{collection:i.name,documentId:String(m.doc.id),locale:a.locale,scheduledFor:r.toISOString(),patch:a.data})})}async purgeExpired(o){let i=this.bySlug[String(o.collection)];if(!i){let a=await this.options.database();await a.transaction(async(r)=>{let l=d(a,r);await l.delete(yt,t("document_id",String(o.id))),await l.delete(g,t("id",String(o.id)))});return}await this.purge(i,{id:String(o.id),actor:null,source:"job",includeTrashed:!0},{retention:!0})}async clearSchedule(o){let i=await this.options.database();await i.transaction((a)=>i.mutate(a,{kind:"update",table:g,where:t("id",o),set:{scheduled_at:null,scheduled_patch:null},returning:!1}))}async recordFailure(o,i,a){let r=a instanceof Error?a.message:String(a),l=await this.options.database(),f=new Date;await l.transaction(async(h)=>{await d(l,h).insert("jobs",{id:ge("job"),type:o,payload:i,status:"failed",run_at:f,attempts:1,locked_at:null,locked_by:null,completed_at:null,error:r,created_at:f}),await this.appendEvents(h,[{type:"job.failed",data:{job:o,error:r,...i},previous:null}],{actor:null})}),this.scheduleDelivery()}async runWrite(o){let i=await this.options.database(),a=await this.outboxWorker(),r=this.pipeline(o.collection.name),l=new tt,f=await i.transaction(async(h)=>{let m=d(i,h),R=await this.replay(m,o);if(R)return R;let v={actor:o.actor,collection:o.collection.name,operation:xe[o.intent],locale:o.locale.locale,tx:h,db:m,cms:this.instance(),events:l,source:o.source,meta:{}},D=await o.step({adapter:i,tx:h,db:m,hooks:r,context:v});if(D===null)return null;if(this.emitDocumentEvents(l,o,D),await this.syncMedia(m,o,D,l),o.emit?.(l,D),await a.append(h,l.take(),this.outboxMeta(o,D)),D.after!==!1)await this.runAfter(r,o,D,v);return await a.append(h,l.take(),this.outboxMeta(o,D)),await this.writeActivity(m,o,D),await this.recordIdempotency(m,o,D),await this.expand(i,h,[D.doc],o.collection,o.locale,o,o.actor),D});if(!f)return null;if(!("replayed"in f))this.scheduleDelivery();return this.redact([f.doc],o.collection,o.actor,o.locale),f.doc}async replay(o,i){let a=i.idempotencyKey;if(a===void 0)return null;let r=await o.findOne(Oe,t("idempotency_key",a));if(!r)return null;return{doc:p(r.result),previous:null,changed:[],replayed:!0}}async recordIdempotency(o,i,a){let r=i.idempotencyKey;if(r===void 0)return;await o.insert(Oe,{id:w("aim"),idempotency_key:r,run_id:i.runId??"",collection:i.collection.name,document_id:String(a.doc.id),result:a.doc,created_at:new Date})}async runAfter(o,i,a,r){let l=xe[i.intent];if(l==="create"){await De(o.createAfter,a.doc,r);return}if(l==="update"){await De(o.updateAfter,{doc:a.doc,previous:a.previous},r);return}await De(o.deleteAfter,a.doc,r)}emitDocumentEvents(o,i,a){let r=(f)=>({collection:i.collection.name,documentId:String(a.doc.id),locale:i.locale.locale,document:ae(f)});switch(i.intent){case"create":{o.emit("document.created",r(a.doc),null);return}case"trash":{o.emit("document.trashed",{...r(a.doc),purgeAfter:a.doc.purgeAfter??null},null);return}case"restore":{o.emit("document.restored",r(a.doc),null);return}case"purge":{o.emit("document.purged",r(a.doc),null);return}case"schedule":{o.emit("document.scheduled",{...r(a.doc),scheduledAt:a.doc.scheduledAt??null,patch:ae(a.doc.scheduledPatch??null)},null);return}case"unschedule":{o.emit("document.schedule.cancelled",{...r(a.doc),scheduledAt:a.previous?.scheduledAt??null},null);return}case"update":break}let l=a.previous;o.emit("document.updated",r(a.doc),r(l));for(let f of a.changed)o.emit("document.field.changed",{collection:i.collection.name,documentId:String(a.doc.id),locale:i.locale.locale,field:f,value:ae(a.doc[f]??null)},{field:f,value:ae(l[f]??null)})}async syncMedia(o,i,a,r){let l=this.options.config.uploads,f=a.releaseMedia===!0;if(!f&&a.stored===void 0)return;if(!f&&!this.referencesMedia(i.collection))return;let h=await Ht({db:o,collection:i.collection.name,documentId:String(a.doc.id),references:f?null:Wt(i.collection,a.stored??{}),lifecycle:l!==void 0,retention:l?.retention,now:new Date}),m=(R)=>({mediaId:R,collection:i.collection.name,documentId:String(a.doc.id)});for(let R of h.orphaned)r.emit("media.orphaned",m(R));for(let R of h.reclaimed)r.emit("media.reclaimed",m(R))}referencesMedia(o){let i=this.media.get(o.name);if(i!==void 0)return i;let a=Ut(o);return this.media.set(o.name,a),a}async writeActivity(o,i,a){await o.insert(bt,{id:ge("act"),actor_id:i.actor?.id??null,actor_source:i.actor?.source??null,action:Ct(i.intent),source:i.source,collection:i.collection.name,document_id:String(a.doc.id),locale:i.locale.locale,changes:{fields:a.changed,...i.runId===void 0?{}:{runId:i.runId}},ip:null,created_at:new Date})}scope(o,i,a,r){let l=[t("collection",o.slug)];if(r!==!0)l.push(t("deleted_at",null));if(i)l.push(i);if(a)l.push(a);return s(...l)}async load(o,i,a,r,l){let f=l.bypassAccess===!0?void 0:await C(a,{actor:l.actor,operation:l.operation,locale:l.locale.locale,rbac:this.options.config.rbac}),m=(await o.query(i,{table:g,where:this.scope(a,t("id",r),f,l.includeTrashed),limit:1}))[0];if(!m)throw e.notFound(`No ${a.name} with id "${r}"`);return m}async patch(o,i,a,r,l){let f=sn(a.revision),h=f+1,m=String(a.id),R=await o.mutate(i,{kind:"update",table:g,where:l===void 0?t("id",m):s(t("id",m),t("revision",l)),set:{...r,revision:h}});if(l!==void 0&&R.count===0)throw je(l,f);return R.rows[0]??{...a,...r,revision:h}}async assertAllowed(o,i,a,r,l){if(await C(o,{actor:a,operation:i,locale:r.locale,rbac:this.options.config.rbac,...l===void 0?{}:{record:l}})&&i==="create")throw new e(`access.create on "${o.name}" returned a filter; a create has no row to filter. Return true or false.`,{status:500,code:"invalid_access_rule"})}requireCollection(o){let i=this.byName[o];if(!i)throw e.notFound(`No collection named "${o}"`);return i}purgeAt(o){let i=this.options.config.trash.purgeAfter;if(i===!1)return null;return new Date(o.getTime()+b(i))}async expand(o,i,a,r,l,f,h){if(!f.depth)return;await new ot({adapter:o,tx:i,locale:l,actor:h,rbac:this.options.config.rbac,collections:this.byName,...f.includeTrashed===void 0?{}:{includeTrashed:f.includeTrashed}}).expand(a,r,f.depth)}redact(o,i,a,r){if(!Yt(i))return;for(let l of o)le(l,i,a,r.locale)}pipeline(o){let i=this.pipelines.get(o);if(i)return i;let a=Xe(this.options.config,o);return this.pipelines.set(o,a),a}outboxMeta(o,i){return{actor:o.actor,collection:o.collection.name,documentId:String(i.doc.id)}}async outboxWorker(){if(this.outbox)return this.outbox;let o=await this.options.database();return this.outbox=new nt(o,this.options.dispatch),this.outbox}scheduleDelivery(){this.delivery=this.delivery.then(async()=>{await(await this.outboxWorker()).drain()}).catch(()=>{return})}instance(){if(!this.cms)throw new e("The engine was used before it was bound.",{status:500,code:"engine_unbound"});return this.cms}}function V(o){return`glb_${o.slug}`}function gt(o){let i=o&&o.length>0?[...o]:[{path:"updated_at",direction:"desc"}];if(!i.some((a)=>a.path==="id"))i.push({path:"id",direction:i[i.length-1]?.direction??"desc"});return i}function wt(o){if(o===void 0)return ft;if(!Number.isInteger(o)||o<1)throw new e(`limit must be a positive integer, received ${o}`,{status:400,code:"invalid_pagination"});return Math.min(o,mt)}function vt(o){let i=o instanceof Date?o:new Date(o);if(Number.isNaN(i.getTime()))throw e.validation(`"${String(o)}" is not a date`);return i}function je(o,i){return new e(`This document has changed since you read it (expected revision ${o}, found ${i}). Reload it and apply your change again.`,{status:409,code:"revision_conflict",details:{expectedRevision:o,revision:i}})}function he(o,i){if(o===void 0)return;if(!Number.isInteger(o)||o<1)throw e.validation(`expectedRevision has to be a positive integer, received ${String(o)}.`);let a=sn(i.revision);if(a!==o)throw je(o,a)}function Ct(o){switch(o){case"create":return"document.created";case"update":return"document.updated";case"trash":return"document.trashed";case"restore":return"document.restored";case"purge":return"document.purged";case"schedule":return"document.scheduled";case"unschedule":return"document.schedule.cancelled"}}function ae(o){return JSON.parse(JSON.stringify(o??null))}var qt={af:"Afrikaans",am:"Amharic",ar:"Arabic",az:"Azerbaijani",be:"Belarusian",bg:"Bulgarian",bn:"Bengali",bs:"Bosnian",ca:"Catalan",cs:"Czech",cy:"Welsh",da:"Danish",de:"German",el:"Greek",en:"English",eo:"Esperanto",es:"Spanish",et:"Estonian",eu:"Basque",fa:"Persian",fi:"Finnish",fil:"Filipino",fo:"Faroese",fr:"French",ga:"Irish",gl:"Galician",gu:"Gujarati",he:"Hebrew",hi:"Hindi",hr:"Croatian",hu:"Hungarian",hy:"Armenian",id:"Indonesian",is:"Icelandic",it:"Italian",ja:"Japanese",ka:"Georgian",kk:"Kazakh",km:"Khmer",kn:"Kannada",ko:"Korean",ku:"Kurdish",ky:"Kyrgyz",lo:"Lao",lt:"Lithuanian",lv:"Latvian",mk:"Macedonian",ml:"Malayalam",mn:"Mongolian",mr:"Marathi",ms:"Malay",mt:"Maltese",my:"Burmese",nb:"Norwegian Bokmål",ne:"Nepali",nl:"Dutch",nn:"Norwegian Nynorsk",no:"Norwegian",pa:"Punjabi",pl:"Polish",ps:"Pashto",pt:"Portuguese",ro:"Romanian",ru:"Russian",si:"Sinhala",sk:"Slovak",sl:"Slovenian",sq:"Albanian",sr:"Serbian",sv:"Swedish",sw:"Swahili",ta:"Tamil",te:"Telugu",th:"Thai",tk:"Turkmen",tl:"Tagalog",tr:"Turkish",tt:"Tatar",uk:"Ukrainian",ur:"Urdu",uz:"Uzbek",vi:"Vietnamese",zh:"Chinese",zu:"Zulu"},kt={AR:"Argentina",AT:"Austria",AU:"Australia",BE:"Belgium",BR:"Brazil",CA:"Canada",CH:"Switzerland",CL:"Chile",CN:"China",CO:"Colombia",CZ:"Czechia",DE:"Germany",DK:"Denmark",ES:"Spain",FI:"Finland",FR:"France",GB:"United Kingdom",HK:"Hong Kong",IE:"Ireland",IN:"India",IT:"Italy",JP:"Japan",KR:"South Korea",MX:"Mexico",NL:"Netherlands",NO:"Norway",NZ:"New Zealand",PL:"Poland",PT:"Portugal",RU:"Russia",SE:"Sweden",TW:"Taiwan",UA:"Ukraine",US:"United States",ZA:"South Africa"},Rt=new Set(["ar","arc","dv","fa","he","ku","ps","sd","ug","ur","yi"]);function Lt(o){let i=qt[o];if(i)return i;let[a,r]=o.split("-"),l=a===void 0?void 0:qt[a.toLowerCase()];if(!l)return o;if(r===void 0)return l;let f=r.toUpperCase();return`${l} (${kt[f]??f})`}function Ft(o){let i=o.split("-")[0];return i!==void 0&&Rt.has(i.toLowerCase())}function pn(o){return o.i18n.locales.map((i)=>({code:i,name:Lt(i),rtl:Ft(i),isDefault:i===o.i18n.defaultLocale}))}var K="webhooks",Z="webhook_deliveries",_t=25,Ot=200,xt=5,St="10s";function Jt(o){let{config:i}=o,a=(y,T)=>(o.fetch??globalThis.fetch)(y,T),r=o.now??(()=>new Date),l=i.webhooks,f=l?.delivery?.retries??xt,h=b(l?.delivery?.timeout??St),m=l?.delivery?.dlq!==!1,R=l?.delivery?.backoff==="linear",v=()=>{if(l?.enabled)return;throw new e("Webhooks are switched off; set webhooks.enabled to true.",{status:501,code:"webhooks_disabled"})},D=(y)=>R?y*30000:Math.min(3600000,1000*2**y),B=async()=>{let y=await o.database();return y.transaction((T)=>y.query(T,{table:K,where:t("active",!0)}))},H=async(y,T,J,E=r())=>{let x=await o.database(),P=Number(y.attempt??0)+1;if((await x.transaction((N)=>x.mutate(N,{kind:"update",table:Z,where:s(t("id",String(y.id)),t("status","pending"),t("attempt",Number(y.attempt??0)),t("next_attempt_at",y.next_attempt_at==null?null:new Date(c(y.next_attempt_at))),k(t("next_attempt_at",null),j("next_attempt_at",E))),set:{attempt:P,next_attempt_at:new Date(E.getTime()+h+30000)},returning:!1}))).count!==1)return ie(y);if(P>f){let N={status:"failed",next_attempt_at:null,error:"Delivery lease expired; attempt budget exhausted."};return await x.transaction((se)=>d(x,se).update(Z,s(t("id",String(y.id)),t("attempt",P)),N)),ie({...y,...N,attempt:P})}let F=typeof T.secret==="string"&&T.secret||l?.signing?.secret||"",G={"content-type":"application/json","user-agent":"heyo-cms","x-heyo-event-id":String(y.event_id),"x-heyo-event-type":String(y.event_type),"x-heyo-delivery-id":String(y.id),"x-heyo-attempt":String(P),...It(T.headers)};if(F.length>0)G[be]=await we(J,F);let Q=null,ue=null,te=null;try{let N=await a(String(T.url),{method:"POST",headers:G,body:J,signal:AbortSignal.timeout(h)});if(Q=N.status,ue=await Pt(N),!N.ok)te=`Responded ${N.status}.`}catch(N){te=N instanceof Error?N.message:String(N)}let ye=te===null,pe=P>=f,ve=r(),ke=ye?{status:"delivered",attempt:P,response_status:Q,response_body:ue,error:null,next_attempt_at:null,delivered_at:ve}:{status:pe?"failed":"pending",attempt:P,response_status:Q,response_body:ue,error:te,next_attempt_at:pe?null:new Date(ve.getTime()+D(P)),delivered_at:null},Fe=await x.transaction(async(N)=>(await d(x,N).update(Z,s(t("id",String(y.id)),t("status","pending"),t("attempt",P)),ke),{...y,...ke}));if(!ye&&pe&&m)await(await o.database()).transaction((se)=>o.emit(se,[{type:"job.failed",data:{job:"webhook-delivery",webhookId:String(y.webhook_id),deliveryId:String(y.id),eventId:String(y.event_id),eventType:String(y.event_type),attempts:P,error:te??"unknown"},previous:null}],{actor:null})),o.deliver();return ie(Fe)},M=async(y,T)=>{let J=await o.database(),E=JSON.stringify(T),x=`whd_${T.id}_${String(y.id)}`,P=await J.transaction((F)=>d(J,F).findOne(Z,t("id",x)));if(P)return ie(P);let L=await J.transaction(async(F)=>d(J,F).insert(Z,{id:x,webhook_id:String(y.id),event_id:T.id,event_type:T.type,status:"pending",attempt:0,request_body:T,response_status:null,response_body:null,error:null,next_attempt_at:r(),delivered_at:null,created_at:r()}));return H(L,y,E)};return{get enabled(){return l?.enabled===!0},async list(y={}){v();let T=await o.database();return(await T.transaction((E)=>T.query(E,{table:K,...y.active===void 0?{}:{where:t("active",y.active)},orderBy:[u("created_at","desc"),u("id","desc")]}))).map(re)},async get(y){v();let T=await o.database(),J=await T.transaction(async(E)=>d(T,E).findOne(K,t("id",y)));return J?re(J):null},async create(y){v(),Je(y.url),Ee(y.events);let T=await o.database(),J=r();return await T.transaction(async(x)=>{let L=await d(T,x).insert(K,{id:w("whk"),url:y.url,events:y.events,filters:y.filters??null,headers:y.headers??null,secret:y.secret??null,active:y.active!==!1,created_at:J,updated_at:J});return re(L)})},async update(y){if(v(),y.url!==void 0)Je(y.url);if(y.events!==void 0)Ee(y.events);let T=await o.database();return T.transaction(async(J)=>{let E=d(T,J),x=await E.findOne(K,t("id",y.id));if(!x)throw e.notFound("No such webhook.");let P={updated_at:r()};if(y.url!==void 0)P.url=y.url;if(y.events!==void 0)P.events=y.events;if(y.filters!==void 0)P.filters=y.filters;if(y.headers!==void 0)P.headers=y.headers;if(y.secret!==void 0)P.secret=y.secret;if(y.active!==void 0)P.active=y.active;await E.update(K,t("id",y.id),P);let L=await E.findOne(K,t("id",y.id));return re(L??{...x,...P})})},async remove(y){v();let T=await o.database();return T.transaction(async(J)=>{let E=d(T,J);return await E.delete(Z,t("webhook_id",y.id)),await E.delete(K,t("id",y.id))>0})},async deliveries(y={}){v();let T=await o.database(),J=Math.min(Ot,Math.max(1,y.limit??_t)),E=[u("created_at","desc"),u("id","desc")],x=[];if(y.webhookId)x.push(t("webhook_id",y.webhookId));if(y.status)x.push(t("status",y.status));if(y.eventId)x.push(t("event_id",y.eventId));let P=x.length===0?void 0:s(...x),L=await T.transaction((Q)=>T.query(Q,{table:Z,...y.cursor?{where:P===void 0?q(y.cursor,E):s(P,q(y.cursor,E))}:P===void 0?{}:{where:P},orderBy:E,limit:J+1})),F=L.slice(0,J),G=F.at(-1);return{entries:F.map((Q)=>ie(Q,y.includeBody===!0)),limit:J,hasNextPage:L.length>J,cursor:G?W(G,E):null}},async test(y){v();let T=await o.database(),J=await T.transaction(async(P)=>d(T,P).findOne(K,t("id",y.id)));if(!J)throw e.notFound("No such webhook.");let E=y.actor??null,x={id:w("evt"),type:"webhook.test",createdAt:r().toISOString(),actor:E?{id:E.id,source:E.source}:null,data:{message:"A test delivery from Heyo CMS. Verify the signature exactly as you would for a real event.",webhookId:String(J.id)},previous:null};return M(J,x)},async retry(y){v();let T=await o.database(),{delivery:J,subscription:E}=await T.transaction(async(L)=>{let F=d(T,L),G=await F.findOne(Z,t("id",y.id));if(!G)throw e.notFound("No such delivery.");let Q=await F.findOne(K,t("id",String(G.webhook_id)));if(!Q)throw e.notFound("That webhook is gone.");return{delivery:G,subscription:Q}}),x=JSON.stringify(J.request_body??{}),P=await T.transaction(async(L)=>d(T,L).insert(Z,{id:ge("whd"),webhook_id:String(E.id),event_id:String(J.event_id),event_type:String(J.event_type),status:"pending",attempt:0,request_body:J.request_body??null,response_status:null,response_body:null,error:null,next_attempt_at:r(),delivered_at:null,created_at:r()}));return H(P,E,x)},async attemptDelivery(y,T=r()){let J=await o.database(),E=await J.transaction(async(x)=>{let P=d(J,x),L=await P.findOne(Z,t("id",y));if(!L||L.status!=="pending")return null;let F=await P.findOne(K,t("id",String(L.webhook_id)));return F?{row:L,subscription:F}:null});if(!E)return null;return H(E.row,E.subscription,JSON.stringify(E.row.request_body??{}),T)},async dispatch(y){if(l?.enabled!==!0)return;let T=await B();for(let J of T){if(!Tt(J,y))continue;await M(J,y)}},async drain(y={}){let T={attempted:0,delivered:0,failed:0};if(l?.enabled!==!0)return T;let J=await o.database(),E=y.now??r(),x=await J.transaction((P)=>J.query(P,{table:Z,where:s(t("status","pending"),k(t("next_attempt_at",null),j("next_attempt_at",E))),orderBy:[u("next_attempt_at","asc"),u("id","asc")],limit:y.limit??50}));for(let P of x){let L=await J.transaction(async(G)=>d(J,G).findOne(K,t("id",String(P.webhook_id))));if(!L)continue;T.attempted+=1;let F=await H(P,L,JSON.stringify(P.request_body??{}),E);if(F.status==="delivered")T.delivered+=1;else if(F.status==="failed")T.failed+=1}return T},async wants(y){if(l?.enabled!==!0)return!1;return(await B()).some((J)=>$e(J,y))}}}async function Pt(o){let i=o.body?.getReader();if(!i)return"";let a=[],r=0;try{while(r<2000){let{value:h,done:m}=await i.read();if(m)break;let R=h.slice(0,2000-r);a.push(R),r+=R.length}}finally{await i.cancel().catch(()=>{}),i.releaseLock()}let l=new Uint8Array(r),f=0;for(let h of a)l.set(h,f),f+=h.length;return new TextDecoder().decode(l)}function $e(o,i){return We(o.events).some((r)=>{if(r==="*"||r===i)return!0;if(!r.endsWith("*"))return!1;return i.startsWith(r.slice(0,-1))})}function Tt(o,i){if(!$e(o,i.type))return!1;let a=o.filters??null;if(!a)return!0;let r=i.data;if(a.collections?.length){let l=typeof r.collection==="string"?r.collection:null;if(!l||!a.collections.includes(l))return!1}if(a.locales?.length){let l=jt(r);if(l.length>0&&!l.some((f)=>a.locales?.includes(f)))return!1}return!0}function jt(o){if(typeof o.locale==="string")return[o.locale];if(Array.isArray(o.locales))return o.locales.filter((i)=>typeof i==="string");return[]}function re(o){return{id:String(o.id),url:String(o.url),events:We(o.events),filters:o.filters?p(o.filters):null,headers:o.headers?p(o.headers):null,hasSecret:typeof o.secret==="string"&&o.secret.length>0,active:o.active===!0||o.active===1,createdAt:c(o.created_at),updatedAt:c(o.updated_at)}}function ie(o,i=!1){return{id:String(o.id),webhookId:String(o.webhook_id),eventId:String(o.event_id),eventType:String(o.event_type),status:String(o.status)??"pending",attempt:Number(o.attempt??0),responseStatus:o.response_status===null||o.response_status===void 0?null:Number(o.response_status),responseBody:o.response_body===null||o.response_body===void 0?null:String(o.response_body),error:o.error===null||o.error===void 0?null:String(o.error),nextAttemptAt:c(o.next_attempt_at),deliveredAt:c(o.delivered_at),createdAt:c(o.created_at),...i?{requestBody:o.request_body===null||o.request_body===void 0?null:p(o.request_body)}:{}}}function We(o){if(!Array.isArray(o))return[];return o.filter((i)=>typeof i==="string")}function It(o){if(typeof o!=="object"||o===null)return{};let i={};for(let[a,r]of Object.entries(o)){if(a.toLowerCase().startsWith("x-heyo-"))continue;if(a.toLowerCase()===be)continue;if(typeof r==="string")i[a]=r}return i}function Je(o){let i;try{i=new URL(o)}catch{throw e.validation(`"${o}" is not a URL.`)}if(i.protocol!=="https:"&&i.protocol!=="http:")throw e.validation("A webhook URL has to be http or https.")}function Ee(o){if(o.length===0)throw e.validation("A webhook has to subscribe to at least one event type.");for(let i of o)if(!/^[a-z][a-z0-9.]*\*?$|^\*$/.test(i))throw e.validation(`"${i}" is not an event type; use "document.updated", "document.*" or "*".`)}var Et="webhook_deliveries";function Nt(o){return{name:"webhook-retries",failureType:"webhook.delivery",failurePayload:(i)=>({deliveryId:String(i.id),webhookId:String(i.webhook_id),eventId:String(i.event_id),eventType:String(i.event_type),attempt:Number(i.attempt??0)}),due:async(i,a,r)=>{let l=await i.database();return l.transaction((f)=>l.query(f,{table:Et,where:s(t("status","pending"),k(t("next_attempt_at",null),j("next_attempt_at",a))),orderBy:[u("next_attempt_at","asc"),u("id","asc")],limit:r}))},run:async(i,a,r)=>{await o.attemptDelivery(String(a.id),r)}}}var $t=new Set(["activity","admin","ai","auth","globals","jobs","locales","media","openapi.json","panel","roles","trash","users","webhooks"]),Gt=/^[a-z][a-z0-9_]*$/,Kt=/^[a-z][a-zA-Z0-9_]*$/,Vt=/^[a-z][a-z0-9-]*$/,Zt=/^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$/;function Wn(o){return{...o,kind:"collection"}}function Hn(o){return{...o,kind:"global"}}function Bn(o){let i=Qt(o),a=At({collections:i.collections,globals:i.globals,pluginTables:i.plugins.flatMap((x)=>x.schema?.tables??[])}),r=new Map,l,f,m=new rt({config:i,database:()=>E.database(),dispatch:async(x)=>{let P=[...r.get(x.type)??[],...r.get("*")??[]];for(let L of P)await L(x);await H.dispatch(x)}}),R=tn({config:i,database:()=>E.database(),emit:(x,P,L)=>m.appendEvents(x,P,L),deliver:()=>m.deliverSoon()}),v=zt({config:i,database:()=>E.database(),emit:(x,P,L)=>m.appendEvents(x,P,L),deliver:()=>m.deliverSoon()}),D=pn(i),B=Ae({database:()=>E.database()}),H=Jt({config:i,database:()=>E.database(),emit:(x,P,L)=>m.appendEvents(x,P,L),deliver:()=>m.deliverSoon()}),M=ht({config:i,database:()=>E.database(),cms:()=>E,emit:(x,P,L)=>m.appendEvents(x,P,L),deliver:()=>m.deliverSoon()}),y=m.buildJobs();if(i.webhooks?.enabled)y.register(Nt(H));if(i.uploads)y.register(Bt({config:i,database:()=>E.database(),storage:()=>v.storage(),emit:(x,P,L)=>m.appendEvents(x,P,L),deliver:()=>m.deliverSoon()}));let T,J=()=>(T??=Pe(E),T),E={_config:Object.freeze(i),schema:a,collections:o.collections,handler:(x)=>J().handler(x),_router:{routes:()=>J().routes()},api:m.buildApi(),globals:m.buildGlobals(),auth:R,media:v,ai:M,webhooks:H,trash:m.buildTrash(),jobs:y,locales:{list:()=>D},activity:B,inspect(){return{basePath:i.basePath,database:{id:l?.id??"unresolved",capabilities:l?.capabilities??{transactions:!1,sqlMigrations:!1,jsonQuery:!1}},storage:vo(i),collections:wo(i),schema:a,hooks:Dt(i),routes:J().routes(),admin:{path:`${i.basePath}${i.admin.path}`,panel:i.admin.assets?.id??null},plugins:Co(i),auth:ko(i),ai:{enabled:i.ai!==void 0,defaultModel:i.ai?.defaultModel??null,assistant:i.ai!==void 0&&i.ai.assistant?.enabled!==!1,actions:ce(),providers:Object.keys(i.ai?.auth??{}).sort(),panelManagedKeys:i.ai?.storage?.secret!==void 0},webhooks:{enabled:i.webhooks?.enabled===!0,signed:i.webhooks?.signing?.secret!==void 0,retries:i.webhooks?.delivery?.retries??5},editor:de(),jobs:E.jobs.list(),trash:{enabled:i.trash.enabled,purgeAfter:i.trash.purgeAfter===!1?null:i.trash.purgeAfter}}},async database(){if(l)return l;return f??=Promise.resolve(typeof i.database==="function"?i.database():i.database).then((x)=>(x.useSchema(a),l=x,x)),f},on(x,P){let L=r.get(x)??new Set;return L.add(P),r.set(x,L),()=>{L.delete(P)}},drainEvents(x){return m.drainEvents(x)},async close(){await m.settle(),await l?.close?.(),l=void 0,f=void 0,r.clear()}};return m.bind(E),E}function Qt(o){let i=go(o.basePath??me),a=new Set(Ve()),r=o.plugins??[];ro(r);let l=no(o.collections,r),f=io({plugins:r,collections:l,globals:o.globals??{},basePath:i}),h={};for(let[v,D]of Object.entries(l))h[v]=Le(v,D,"collection",a);let m={};for(let[v,D]of Object.entries(o.globals??{}))m[v]=Le(v,D,"global",a);Xt({...h,...m}),eo({...h,...m}),to(o),oo(o,h,m),so({...h,...m}),uo(o),po(o),fo(o),ho(o),mo(o),bo(o);let R=o.trash?.purgeAfter??"30d";if(typeof R==="string")b(R,"trash.purgeAfter");return{basePath:i,database:o.database,admin:{...o.admin,path:yo(o.admin?.path??He)},...o.rbac===void 0?{}:{rbac:o.rbac},i18n:lo(o.i18n),...o.uploads===void 0?{}:{uploads:o.uploads},...o.ai===void 0?{}:{ai:o.ai},...o.webhooks===void 0?{}:{webhooks:o.webhooks},trash:{enabled:o.trash?.enabled??!0,purgeAfter:R},collections:h,globals:m,...o.hooks===void 0?{}:{hooks:o.hooks},...o.databaseHooks===void 0?{}:{databaseHooks:o.databaseHooks},plugins:r,pluginHooks:f,...o.telemetry===void 0?{}:{telemetry:o.telemetry},migrationsDirectory:o.migrations?.directory??Be}}function Le(o,i,a,r){if(!Gt.test(o))throw new n(`collections.${o}`,"a collection name must be lowercase letters, digits and underscores, starting with a letter");let l=i.slug??o.replaceAll("_","-");if(!Vt.test(l))throw new n(`collections.${o}.slug`,`"${l}" is not a URL-safe slug`);if(r.has(o)||r.has(l))throw new n(`collections.${o}`,`"${o}" is a reserved system name; pick another`);if($t.has(l))throw new n(`collections.${o}`,`"${l}" is a URL the CMS serves itself; give the collection another slug`);let f={};for(let[h,m]of Object.entries(i.fields)){if(!Kt.test(h))throw new n(`collections.${o}.fields.${h}`,"a field name must be letters, digits and underscores, starting with a lowercase letter");if(m.required&&m.admin?.hidden===!0)throw new n(`collections.${o}.fields.${h}.admin.hidden`,"a hidden field cannot be required; remove required or show the field");f[h]=m}if(Object.keys(f).length===0)throw new n(`collections.${o}.fields`,"a collection needs at least one field");return{name:o,slug:l,label:i.label??Ao(o),kind:a,fields:f,access:i.access??{},...i.admin===void 0?{}:{admin:i.admin}}}function Xt(o){let i=new Map;for(let a of Object.values(o)){let r=i.get(a.slug);if(r)throw new n(`collections.${a.name}.slug`,`"${a.slug}" is already used by "${r}"; slugs are URLs and index names`);i.set(a.slug,a.name)}}function eo(o){let i=new Set([...Object.keys(o),...Ve()]);for(let a of Object.values(o))for(let[r,l]of Object.entries(a.fields)){if(!l.relationTo)continue;if(!i.has(l.relationTo))throw new n(`collections.${a.name}.fields.${r}`,`relation points at "${l.relationTo}", which is not a collection`)}}function to(o){let i=o.ai;if(i&&i.chat!==void 0)throw new n("ai.chat","document chat was replaced by the panel-wide assistant. Use ai.assistant, which takes a model, instructions and limits; what the agent may read and write now comes from the configuration and the actor at runtime");let a={...o.collections,...o.globals??{}};for(let[r,l]of Object.entries(a)){if(l?.ai===void 0)continue;throw new n(`collections.${r}.ai`,"per-collection ai.chat was removed with document chat. Delete the key; the assistant reads the collection through the same access control as everything else")}}function oo(o,i,a){for(let r of Object.keys(o.databaseHooks??{}))if(!(r in i)&&!(r in a))throw new n(`databaseHooks.${r}`,"no collection or global with this name")}function no(o,i){let a={...o},r=new Map;for(let l of i)for(let[f,h]of Object.entries(l.schema?.collections??{})){if(f in o)throw new n(`plugins.${l.id}.schema.collections.${f}`,`the configuration already declares a collection called "${f}"`);let m=r.get(f);if(m)throw new n(`plugins.${l.id}.schema.collections.${f}`,`"${m}" already declares a collection called "${f}"`);r.set(f,l.id),a[f]=h}return a}function io(o){let i=[],a=new Map;for(let r of o.plugins){if(!r.extendCollections)continue;let l=r.extendCollections({collections:o.collections,basePath:o.basePath});for(let f of l){let h=o.collections[f.collection]??o.globals[f.collection];if(!h)throw new n(`plugins.${r.id}.extendCollections`,`patches "${f.collection}", which is not a collection or a global`);for(let[m,R]of Object.entries(f.fields??{})){let v=a.get(`${f.collection}.${m}`);if(m in h.fields)throw new n(`plugins.${r.id}.extendCollections`,v?`"${v}" already added "${m}" to ${f.collection}`:`${f.collection} already has a field called "${m}"`);a.set(`${f.collection}.${m}`,r.id),h.fields={...h.fields,[m]:R}}if(f.hooks)i.push({plugin:r.id,collection:f.collection,hooks:f.hooks,priority:0})}}return i}function so(o){for(let i of Object.values(o))for(let[a,r]of Object.entries(i.fields)){if(r.aiGenerate!==void 0)Me(i,a,r.aiGenerate,`collections.${i.name}.fields.${a}.aiGenerate`);for(let[l,f]of Object.entries(r.ai??{})){if(f!==!0)Me(i,a,f,`collections.${i.name}.fields.${a}.ai.${l}`);let h=z(l),m=`collections.${i.name}.fields.${a}.ai.${l}`;if(!h){if(f===!0||f.prompt===void 0)throw new n(m,"is not a registered AI action; register it with defineAiAction() or give it a prompt");continue}if(!h.appliesTo.includes("*")&&!h.appliesTo.includes(r.type))throw new n(m,`does not apply to a ${r.type} field; it applies to ${h.appliesTo.join(", ")}`);if(h.requiresLocalized&&!r.localized)throw new n(m,"needs a localized field; this one stores a single value for every language")}}}function Me(o,i,a,r){if(a.context!==void 0&&!Array.isArray(a.context))throw new n(`${r}.context`,"must be an array of field names");let l=new Set;for(let f of a.context??[]){if(typeof f!=="string"||!o.fields[f]||f===i||l.has(f))throw new n(`${r}.context`,`"${f}" must name a different, existing field of ${o.name} (only once)`);l.add(f)}if(a.maxLength!==void 0&&(!Number.isInteger(a.maxLength)||a.maxLength<1))throw new n(`${r}.maxLength`,"must be a positive integer");if(a.model&&(!a.model.provider||!a.model.model))throw new n(`${r}.model`,"needs a provider and a model")}function ro(o){let i=new Set;for(let r of o){if(i.has(r.id))throw new n(`plugins.${r.id}`,"two plugins share this id");i.add(r.id)}let a=new Map;for(let r of o)for(let l of r.routes??[]){let f=`${l.method} ${l.path}`,h=a.get(f);if(h)throw new n(`plugins.${r.id}.routes`,`"${f}" is already registered by "${h}"`);a.set(f,r.id)}}function lo(o){let i=o?.locales,a=o?.defaultLocale??i?.[0]??"en";return{defaultLocale:a,locales:i??[a]}}function uo(o){let i=o.i18n;if(!i)return;let a=i.locales;if(a!==void 0){if(a.length===0)throw new n("i18n.locales","at least one locale; leave the section out for a single-language site");for(let l of a)if(!Zt.test(l))throw new n("i18n.locales",`"${l}" is not a locale code; use a BCP 47 tag such as "en" or "pt-BR"`);if(new Set(a).size!==a.length)throw new n("i18n.locales","duplicate locale codes")}let r=i.defaultLocale;if(r!==void 0&&a&&!a.includes(r))throw new n("i18n.defaultLocale",`"${r}" is not in i18n.locales (${a.map((l)=>`"${l}"`).join(", ")})`)}function po(o){let i=o.rbac;if(!i)return;for(let[a,r]of Object.entries(i.roles)){if(!/^[a-z][a-z0-9_-]*$/.test(a))throw new n(`rbac.roles.${a}`,"a role name must be lowercase letters, digits, dashes and underscores, starting with a letter");for(let l of r){if(l==="*")continue;if(!/^[a-z0-9_*-]+:[a-z0-9_*-]+$/.test(l))throw new n(`rbac.roles.${a}`,`"${l}" is not a permission; use "collection:action" or "*"`)}}if(i.defaultRole&&!(i.defaultRole in i.roles))throw new n("rbac.defaultRole",`"${i.defaultRole}" is not one of the configured roles`)}function fo(o){let i=o.admin?.auth;if(!i)return;let a=new Set;for(let r of i.methods){if(a.has(r))throw new n("admin.auth.methods",`"${r}" is listed twice`);a.add(r)}for(let r of i.apiKeys?.scopes??[])if(!Re(r))throw new n("admin.auth.apiKeys.scopes",`"${r}" is not a scope; use "read", "write", "delete", "*" or "collection:action"`);if(i.sso?.mapRoles&&!o.rbac)throw new n("admin.auth.sso.mapRoles","maps claims onto roles, but no roles are configured; add rbac.roles")}function ho(o){let i=o.uploads;if(!i)return;if(i.limits?.maxFileSize)ee(i.limits.maxFileSize,"uploads.limits.maxFileSize");let a=i.retention?.purgeAfter;if(typeof a==="string")b(a,"uploads.retention.purgeAfter");let r=i.images,l=r?.quality;if(l!==void 0&&(l<1||l>100))throw new n("uploads.images.quality","must be between 1 and 100");for(let[f,h]of Object.entries(r?.variants?.sizes??{})){if(!/^[a-z][a-z0-9-]*$/.test(f))throw new n(`uploads.images.variants.sizes.${f}`,"a size name ends up in a URL; use lowercase letters, digits and dashes");if(Zn.includes(f))throw new n(`uploads.images.variants.sizes.${f}`,`"${f}" is a media endpoint; pick another size name`);if(h.width===void 0&&h.height===void 0)throw new n(`uploads.images.variants.sizes.${f}`,"needs a width, a height, or both");if(h.fit==="cover"&&(h.width===void 0||h.height===void 0))throw new n(`uploads.images.variants.sizes.${f}`,'fit: "cover" needs both a width and a height')}if(r&&!r.processor){let f=r.convert!==void 0?"convert":r.maxDimensions!==void 0?"maxDimensions":r.variants?.mode==="pregenerate"?'variants.mode: "pregenerate"':null;if(f)throw new n("uploads.images.processor",`${f} has to render pixels, and nothing here can. Add a processor (sharpImages() from "@heyo-sh/heyo-cms/uploads"), or drop the option.`)}}function mo(o){let i=o.ai;if(!i)return;let a=new Set(Object.keys(i.auth??{})),r=i.storage?.secret!==void 0;if(a.size===0&&!r&&i.complete===void 0)throw new n("ai.auth","AI is configured without credentials. Add ai.auth, set ai.storage.secret to manage keys in the panel, or remove the section to disable AI");if(!r&&i.complete===void 0&&!a.has(i.defaultModel.provider))throw new n("ai.defaultModel.provider",`"${i.defaultModel.provider}" has no entry in ai.auth`);let l=i.assistant,f=l?.model?.provider;if(f&&!r&&i.complete===void 0&&!a.has(f))throw new n("ai.assistant.model.provider",`"${f}" has no entry in ai.auth`);for(let[h,m]of[["maxTurns",1],["maxToolCalls",1],["timeoutMs",1000]]){let R=l?.[h];if(R===void 0)continue;if(!Number.isInteger(R)||R<m)throw new n(`ai.assistant.${h}`,`must be an integer of at least ${m}; it is a budget the server enforces, not a hint to the model`)}if(i.storage&&i.storage.secret.length<16)throw new n("ai.storage.secret","must be at least 16 characters; it encrypts the provider keys in the database")}function bo(o){let i=o.webhooks;if(!i?.enabled)return;if(!i.signing?.secret)throw new n("webhooks.signing.secret","webhooks must be signed; set a secret");if(i.delivery?.timeout)b(i.delivery.timeout,"webhooks.delivery.timeout")}function yo(o){let i=o.trim();if(!i.startsWith("/"))throw new n("admin.path",'must start with "/"');if(/[?#]/.test(i)||i.includes("//"))throw new n("admin.path","cannot contain a query, a fragment or an empty segment");let a=O(i);if(a.length===0)return"";return a}function go(o){let i=o.trim();if(!i.startsWith("/"))throw new n("basePath",'must start with "/"');if(/[?#]/.test(i))throw new n("basePath","cannot contain a query or fragment");if(i.includes("//"))throw new n("basePath","cannot contain empty segments");let a=O(i);if(a.length===0)throw new n("basePath",'cannot be "/"');return a}function wo(o){return[...Object.values(o.collections),...Object.values(o.globals)].map((i)=>({name:i.name,slug:i.slug,kind:i.kind,fields:Object.entries(i.fields).map(([a,r])=>({name:a,type:r.type,localized:r.localized,required:r.required}))}))}function vo(o){let i=o.uploads;if(!i)return null;let a=i.retention?.purgeAfter??"30d";return{id:typeof i.storage==="function"?"unresolved":i.storage.id,variants:i.images?.variants?.mode??null,processor:i.images?.processor?.id??null,purgeAfter:a===!1?null:a}}function Co(o){return o.plugins.map((i)=>({id:i.id,collections:Object.keys(i.schema?.collections??{}).sort(),tables:(i.schema?.tables??[]).map((a)=>a.name).sort(),routes:i.routes?.length??0,hooks:(i.hooks?.length??0)+o.pluginHooks.filter((a)=>a.plugin===i.id).length,migrations:(i.migrations??[]).map((a)=>a.id),client:i.client!==void 0,admin:i.admin!==void 0}))}function ko(o){let i=o.admin.auth;return{methods:i?.methods??[],twoFactor:i?.twoFactor===!0,apiKeys:i?.apiKeys?.enabled===!0,sso:i?.sso?.issuer??null,roles:Object.keys(o.rbac?.roles??{}).sort(),customRoles:o.rbac?.customRoles===!0}}function Ao(o){return o.replaceAll("_"," ").replace(/^./,(i)=>i.toUpperCase())}function it(o="system"){return{id:o,source:"session",roles:["admin"],permissions:["*"]}}
|
|
2
|
-
export{Xe,Se,De,Dt,et,tt,nt,ot,un,Mt,rt,V,qt,Lt,Ft,pn,Jt,Nt,Wn,Hn,Bn,it};
|
package/dist/index-vxw0a03g.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
function s(...e){return{kind:"and",conditions:e.filter(o)}}function k(...e){return{kind:"or",conditions:e.filter(o)}}function Fn(e){return{kind:"not",condition:e}}function Bo(e,r,n){return{kind:"compare",path:e,operator:r,value:n}}function t(e,r){return{kind:"compare",path:e,operator:"eq",value:r}}function Jn(e,r){return{kind:"compare",path:e,operator:"ne",value:r}}function Ke(e,r){return{kind:"compare",path:e,operator:"gt",value:r}}function zo(e,r){return{kind:"compare",path:e,operator:"gte",value:r}}function U(e,r){return{kind:"compare",path:e,operator:"lt",value:r}}function j(e,r){return{kind:"compare",path:e,operator:"lte",value:r}}function I(e,r){return{kind:"compare",path:e,operator:"in",value:r}}function Vo(e,r){return{kind:"compare",path:e,operator:"nin",value:r}}function te(e,r,n=!1){return{kind:"compare",path:e,operator:n?"ilike":"like",value:r}}function Go(e,r){return{kind:"compare",path:e,operator:"contains",value:r}}function oe(e,r=!0){return{kind:"compare",path:e,operator:"exists",value:r}}function u(e,r="asc"){return{path:e,direction:r}}function Ho(e,r){if(!e)return r;if(!r)return e;return s(e,r)}function Ko(e,r){let n=Ho(e.where,r);return n===void 0?e:{...e,where:n}}function o(e){return e!==void 0}
|
|
2
|
-
export{s,k,Fn,Bo,t,Jn,Ke,zo,U,j,I,Vo,te,Go,oe,u,Ho,Ko};
|
package/dist/index-wj8y1xcj.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{s,k,t,Jn,Ke,U,j,I,te,oe,u}from"./index-vxw0a03g.js";import{P,c,p}from"./index-2z1qe5mw.js";import{d}from"./index-9g2n7xa6.js";import{b,ee}from"./index-cbwwtcm4.js";import{w}from"./index-2kb5nbxx.js";import{e}from"./index-x72d1hzh.js";var O="media",z="media_usages",ze="mediaId";function Ut(n){return Object.values(n.fields).some((r)=>r.type==="media"||r.type==="richText"||r.relationTo==="media")}function Wt(n,r){let i=new Map,a=(o,l,m)=>{if(!o)return;i.set(`${o}|${l}|${m}`,{mediaId:o,field:l,locale:m})};for(let[o,l]of Object.entries(n.fields)){let m=l.type==="media"||l.relationTo==="media",x=l.type==="richText";if(!m&&!x)continue;for(let[v,T]of Ge(r[o],l.localized)){if(m){for(let N of We(T))a(N,o,v);continue}for(let N of Xe(T))a(N,o,v)}}return[...i.values()]}async function Ht(n){let{db:r,documentId:i}=n,a=await r.find(z,t("document_id",i)),o=new Map((n.references??[]).map((v)=>[`${v.mediaId}|${v.field}|${v.locale}`,v])),l=new Set,m=[];for(let v of a){let T=`${String(v.media_id)}|${String(v.field)}|${String(v.locale??"")}`;if(o.delete(T))continue;m.push(String(v.id)),l.add(String(v.media_id))}if(m.length>0)await r.delete(z,I("id",m));let x=new Set;for(let v of o.values())x.add(v.mediaId),await r.insert(z,{id:w("mus"),media_id:v.mediaId,collection:n.collection,document_id:i,field:v.field,locale:v.locale,created_at:n.now});if(!n.lifecycle)return{orphaned:[],reclaimed:[]};return{orphaned:await Be(n,[...l]),reclaimed:await Le(n,[...x])}}async function Be(n,r){if(r.length===0)return[];if(n.retention?.orphanAfterUnreferenced===!1)return[];let i=[];for(let a of r){if((await n.db.find(z,t("media_id",a))).length>0)continue;if(await n.db.update(O,s(t("id",a),t("status","active")),{status:"orphaned",orphaned_at:n.now,purge_after:Ve(n.retention,n.now),updated_at:n.now})>0)i.push(a)}return i}async function Le(n,r){if(r.length===0)return[];if(n.retention?.reclaimOnReference===!1)return[];let i=[];for(let a of r)if(await n.db.update(O,s(t("id",a),Jn("status","active")),{status:"active",orphaned_at:null,purge_after:null,purge_error:null,updated_at:n.now})>0)i.push(a);return i}function Ve(n,r){let i=n?.purgeAfter??"30d";if(i===!1)return null;return new Date(r.getTime()+b(i))}function Ge(n,r){if(!r)return[["",n]];if(typeof n!=="object"||n===null||Array.isArray(n))return[];return Object.entries(n)}function We(n){if(typeof n==="string")return n.length>0?[n]:[];if(Array.isArray(n))return n.filter((r)=>typeof r==="string");return[]}function Xe(n){let r=[],i=[n??null];while(i.length>0){let a=i.pop();if(Array.isArray(a)){i.push(...a);continue}if(typeof a!=="object"||a===null)continue;for(let[o,l]of Object.entries(a)){if(o===ze&&typeof l==="string"){r.push(l);continue}if(l!==null&&typeof l==="object")i.push(l)}}return r}function W(n,r){let i=r.map((a)=>{let o=He(n,a.path);return{path:a.path,value:o instanceof Date?o.toISOString():Ye(o),date:o instanceof Date}});return Ze(JSON.stringify(i))}function q(n,r){let i=Qe(n);if(i.length!==r.length)throw new e("This cursor does not match the requested sort order.",{status:400,code:"invalid_cursor"});let a=[];for(let o=0;o<r.length;o+=1){let l=[];for(let v=0;v<o;v+=1){let T=i[v];l.push(t(T.path,ie(T)))}let m=i[o],x=r[o].direction;l.push(x==="desc"?U(m.path,ie(m)):Ke(m.path,ie(m))),a.push(s(...l))}return k(...a)}function Qe(n){try{let r=JSON.parse(et(n));if(!Array.isArray(r))throw Error("not a cursor");return r}catch{throw new e("This cursor is not readable.",{status:400,code:"invalid_cursor"})}}function ie(n){return n.date&&typeof n.value==="string"?new Date(n.value):n.value}function He(n,r){if(r in n)return n[r];let i=r.split("."),a=n.data??n;for(let o of i){if(typeof a!=="object"||a===null)return;a=a[o]}return a}function Ye(n){if(n===void 0||n===null)return null;if(typeof n==="object")return null;return n}function Ze(n){let r=new TextEncoder().encode(n),i="";for(let a of r)i+=String.fromCharCode(a);return btoa(i).replaceAll("+","-").replaceAll("/","_").replace(/=+$/,"")}function et(n){let r=n.replaceAll("-","+").replaceAll("_","/"),i=atob(r.padEnd(Math.ceil(r.length/4)*4,"=")),a=Uint8Array.from(i,(o)=>o.charCodeAt(0));return new TextDecoder().decode(a)}var xe=["crop","variants"];function L(n,r){let i=p(n.metadata),{crop:a,variants:o,...l}=i,m=String(n.storage_key);return{id:String(n.id),filename:String(n.filename),mimeType:String(n.mime_type),size:Number(n.size??0),width:we(n.width),height:we(n.height),storageKey:m,checksum:ae(n.checksum),alt:it(n.alt),focalPoint:nt(n.focal_x,n.focal_y),crop:rt(a),status:tt(n.status),orphanedAt:c(n.orphaned_at),purgeAfter:c(n.purge_after),purgeError:ae(n.purge_error),metadata:l,variants:Array.isArray(o)?o.filter((x)=>typeof x==="string"):[],createdBy:ae(n.created_by),createdAt:c(n.created_at),updatedAt:c(n.updated_at),url:r.url(m)}}function se(n){return JSON.parse(JSON.stringify(n))}function tt(n){return n==="orphaned"||n==="purging"?n:"active"}function nt(n,r){if(n===null||n===void 0)return null;if(r===null||r===void 0)return null;return{x:Number(n),y:Number(r)}}function rt(n){if(typeof n!=="object"||n===null||Array.isArray(n))return null;let r=n,i=["x","y","width","height"].map((a)=>Number(r[a]));if(i.some((a)=>Number.isNaN(a)))return null;return{x:i[0],y:i[1],width:i[2],height:i[3]}}function it(n){let r=p(n),i={};for(let[a,o]of Object.entries(r))if(typeof o==="string")i[a]=o;return i}function we(n){return n===null||n===void 0?null:Number(n)}function ae(n){return n===null||n===void 0?null:String(n)}var ve={jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",avif:"image/avif",svg:"image/svg+xml",tiff:"image/tiff"};function mo(n){return ve[n]}function st(n){return ot(n)??ft(n)??lt(n)??mt(n)??pt(n)??gt(n)}function at(n){let i={"image/jpeg":"jpg","image/png":"png","image/gif":"gif","image/webp":"webp","image/avif":"avif","image/svg+xml":"svg","image/tiff":"tiff","video/mp4":"mp4","video/webm":"webm","audio/mpeg":"mp3","application/pdf":"pdf","application/json":"json","text/plain":"txt","text/csv":"csv"}[n.toLowerCase()];if(i)return i;let a=n.split("/")[1]?.split(";")[0]?.trim();return a&&/^[a-z0-9.+-]+$/i.test(a)?a:"bin"}function ot(n){let r=[137,80,78,71,13,10,26,10];if(n.length<24||!ht(n,r))return null;return B("png",Y(n,16),Y(n,20))}function ft(n){if(n.length<10||K(n,0,3)!=="GIF")return null;return B("gif",Z(n,6),Z(n,8))}function lt(n){if(n.length<30||K(n,0,4)!=="RIFF"||K(n,8,4)!=="WEBP")return null;let r=K(n,12,4);if(r==="VP8X")return B("webp",be(n,24)+1,be(n,27)+1);if(r==="VP8 "){if(n[23]!==157||n[24]!==1||n[25]!==42)return null;return B("webp",Z(n,26)&16383,Z(n,28)&16383)}if(r==="VP8L"){if(n[20]!==47)return null;let i=D(n,21),a=D(n,22),o=D(n,23),l=D(n,24);return B("webp",((a&63)<<8|i)+1,((l&15)<<10|o<<2|(a&192)>>6)+1)}return null}function mt(n){if(n.length<4||n[0]!==255||n[1]!==216)return null;let r=2;while(r+9<n.length){if(n[r]!==255){r+=1;continue}let i=D(n,r+1);if(i===255||i===1||i>=208&&i<=217){r+=2;continue}if(i>=192&&i<=195||i>=197&&i<=199||i>=201&&i<=203||i>=205&&i<=207)return B("jpeg",ce(n,r+7),ce(n,r+5));let o=ce(n,r+2);if(o<2)return null;r+=2+o}return null}function pt(n){if(n.length<16||K(n,4,4)!=="ftyp")return null;let r=K(n,8,4),i=r==="avif"||r==="avis";if(!i&&!(r==="heic"||r==="heix"||r==="mif1"))return null;let o=Math.min(n.length-16,65536);for(let l=16;l<o;l+=1){if(K(n,l,4)!=="ispe")continue;let m=Y(n,l+8),x=Y(n,l+12);if(m>0&&x>0&&m<1e5&&x<1e5)return B(i?"avif":"avif",m,x)}return null}function gt(n){let r=new TextDecoder().decode(n.subarray(0,2048));if(!/<svg[\s>]/i.test(r))return null;let i=(l)=>{let m=new RegExp(`\\b${l}\\s*=\\s*["']([\\d.]+)`,"i").exec(r);return m?Math.round(Number(m[1])):0},a=i("width"),o=i("height");if(a===0||o===0){let l=/\bviewBox\s*=\s*["']\s*[\d.-]+\s+[\d.-]+\s+([\d.]+)\s+([\d.]+)/i.exec(r);if(l)a=Math.round(Number(l[1])),o=Math.round(Number(l[2]))}return B("svg",a,o)}function B(n,r,i){return{format:n,contentType:ve[n],width:r,height:i}}function D(n,r){return n[r]??0}function ce(n,r){return D(n,r)<<8|D(n,r+1)}function Y(n,r){return D(n,r)*16777216+(D(n,r+1)<<16|D(n,r+2)<<8|D(n,r+3))}function Z(n,r){return D(n,r)|D(n,r+1)<<8}function be(n,r){return D(n,r)|D(n,r+1)<<8|D(n,r+2)<<16}function K(n,r,i){let a="";for(let o=0;o<i;o+=1)a+=String.fromCharCode(D(n,r+o));return a}function ht(n,r){return r.every((i,a)=>n[a]===i)}function X(n){return Object.keys(n?.variants?.sizes??{})}function Ae(n,r){let i=n?.variants?.sizes?.[r];if(!i){let a=X(n);throw e.notFound(a.length>0?`No image size named "${r}"; this configuration declares ${a.join(", ")}`:`No image size named "${r}"; this configuration declares none`)}return i}function mn(n,r,i){let a=Ae(n,r),o={...a.width===void 0?{}:{width:a.width},...a.height===void 0?{}:{height:a.height},...a.fit===void 0?{}:{fit:a.fit}};if(n?.quality!==void 0)o.quality=n.quality;if(n?.stripMetadata!==!1)o.stripMetadata=!0;if(n?.focalPoint!==!1&&i.focalPoint)o.position=i.focalPoint;if(n?.crop!==!1&&i.crop)o.crop=i.crop;let l=n?.convert;if(l&&!(l.keep??[]).includes(i.mimeType))o.format=l.to;return o}function Q(n,r){let i=n?.convert;if(!i||(i.keep??[]).includes(r))return r;return`image/${i.to}`}function Me(n,r,i){let a=n.lastIndexOf("/"),o=n.lastIndexOf(".");return`${o>a?n.slice(0,o):n}/${r}.${at(i)}`}function Se(n,r){let i=Ae(n,r),a=new URLSearchParams;if(i.width!==void 0)a.set("w",String(i.width));if(i.height!==void 0)a.set("h",String(i.height));if(i.fit!==void 0)a.set("fit",i.fit);if(n?.quality!==void 0)a.set("q",String(n.quality));return a.toString()}async function Ce(n,r,i,a){if(!n||!n.supports(a.mimeType))return null;return n.transform(r,i,{format:a.mimeType.split("/")[1]??"jpeg",contentType:a.mimeType,width:a.width??0,height:a.height??0})}var yt=86400000,wt=100;async function Ue(n,r,i){if(n.config.uploads?.retention?.purgeAfter===!1)return[];let a=await n.database();return a.transaction((o)=>a.query(o,{table:O,where:s(t("status","orphaned"),oe("purge_after",!0),j("purge_after",r)),orderBy:[u("purge_after","asc"),u("id","asc")],limit:i}))}async function _e(n,r={}){let i={examined:0,purged:0,reclaimed:0,failed:0};if(!n.config.uploads)return i;let a=r.now??new Date,o=await Ue(n,a,r.limit??wt);for(let l of o){i.examined+=1;try{let m=await Ie(n,l,a);if(m==="purged")i.purged+=1;if(m==="reclaimed")i.reclaimed+=1}catch{i.failed+=1}}return i}async function Ie(n,r,i){let a=await n.storage(),o=L(r,a),l=await de(n,async(m,x)=>{if((await x.find(z,t("media_id",o.id))).length>0){if(await x.update(O,s(t("id",o.id),t("status","orphaned")),{status:"active",orphaned_at:null,purge_after:null,purge_error:null,updated_at:i})===0)return"taken";return await Te(n,m,"media.reclaimed",{...o,status:"active",orphanedAt:null,purgeAfter:null}),"reclaimed"}return await x.update(O,s(t("id",o.id),t("status","orphaned")),{status:"purging",updated_at:i})===1?"claimed":"taken"});if(n.deliver(),l!=="claimed")return l;try{return await a.delete(ue(o,n.config.uploads)),await de(n,async(m,x)=>{await x.delete(z,t("media_id",o.id)),await x.delete(O,t("id",o.id)),await Te(n,m,"media.purged",o,{collected:!0})}),n.deliver(),"purged"}catch(m){throw await xt(n,o,m,i),m}}function Bt(n){return{name:"media-gc",failureType:"media.purge",failurePayload:(r)=>({mediaId:String(r.id),storageKey:String(r.storage_key),filename:String(r.filename)}),due:(r,i,a)=>Ue(n,i,a),run:async(r,i)=>{await Ie(n,i,new Date)}}}function ue(n,r){let i=Q(r?.images,n.mimeType),a=new Set([...n.variants,...X(r?.images)]);return[n.storageKey,...[...a].map((o)=>Me(n.storageKey,o,i))]}async function xt(n,r,i,a){let o=i instanceof Error?i.message:String(i);await de(n,async(l,m)=>{await m.update(O,t("id",r.id),{status:"orphaned",purge_after:new Date(a.getTime()+yt),purge_error:o.slice(0,1000),updated_at:a})})}async function Te(n,r,i,a,o={}){await n.emit(r,[{type:i,data:{media:JSON.parse(JSON.stringify(a)),...o},previous:null}],{actor:null,collection:"media",documentId:a.id})}async function de(n,r){let i=await n.database();return i.transaction((a)=>r(a,d(i,a)))}async function ye(n){if(n instanceof Uint8Array)return n;if(n instanceof ArrayBuffer)return new Uint8Array(n);if(typeof Blob<"u"&&n instanceof Blob)return new Uint8Array(await n.arrayBuffer());let r=[],i=n.getReader();for(;;){let{done:a,value:o}=await i.read();if(a)break;if(o)r.push(o)}return G(r)}function G(n){if(n.length===1)return n[0];let r=n.reduce((o,l)=>o+l.byteLength,0),i=new Uint8Array(r),a=0;for(let o of n)i.set(o,a),a+=o.byteLength;return i}function ct(n){return new ReadableStream({start(r){r.enqueue(n),r.close()}})}function qe(n){let r="";for(let i of n)r+=i.toString(16).padStart(2,"0");return r}function zn(n){let r="";for(let i of n)r+=String.fromCharCode(i);return btoa(r)}async function dt(n){let r=typeof n==="string"?new TextEncoder().encode(n):n,i=await crypto.subtle.digest("SHA-256",r);return new Uint8Array(i)}function ut(n,r){switch(r.toLowerCase()){case"image/jpeg":return bt(n);case"image/png":return At(n);case"image/webp":return Mt(n);default:return n}}function bt(n){if(n.length<4||n[0]!==255||n[1]!==216)return n;let r=[n.subarray(0,2)],i=2;while(i+4<=n.length){if(n[i]!==255)break;let a=n[i+1]??0;if(a===216||a===1||a>=208&&a<=215){r.push(n.subarray(i,i+2)),i+=2;continue}if(a===218){r.push(n.subarray(i)),i=n.length;break}let o=(n[i+2]??0)<<8|(n[i+3]??0);if(o<2||i+2+o>n.length)break;if(!vt(a))r.push(n.subarray(i,i+2+o));i+=2+o}if(i<n.length)r.push(n.subarray(i));return G(r)}function vt(n){if(n===254)return!0;if(n===224)return!1;if(n===226)return!1;if(n===238)return!1;return n>=224&&n<=239}function At(n){let r=[137,80,78,71,13,10,26,10];if(n.length<8||!r.every((l,m)=>n[m]===l))return n;let i=new Set(["tEXt","zTXt","iTXt","eXIf","tIME","dSIG"]),a=[n.subarray(0,8)],o=8;while(o+8<=n.length){let l=St(n,o),m=ne(n,o+4,4),x=12+l;if(x<12||o+x>n.length)break;if(!i.has(m))a.push(n.subarray(o,o+x));if(o+=x,m==="IEND")break}return G(a)}function Mt(n){if(n.length<12||ne(n,0,4)!=="RIFF"||ne(n,8,4)!=="WEBP")return n;let r=new Set(["EXIF","XMP "]),i=[],a=12,o=!1;while(a+8<=n.length){let x=ne(n,a,4),v=Ct(n,a+4),T=8+v+v%2;if(a+T>n.length)break;if(r.has(x))o=!0;else i.push(n.subarray(a,a+T));a+=T}if(!o)return n;let l=G(i),m=new Uint8Array(12);return m.set(n.subarray(0,12)),Tt(m,4,l.byteLength+4),G([m,l])}function St(n,r){return(n[r]??0)*16777216+((n[r+1]??0)<<16|(n[r+2]??0)<<8|(n[r+3]??0))}function Ct(n,r){return(n[r]??0)+((n[r+1]??0)<<8)+((n[r+2]??0)<<16)+(n[r+3]??0)*16777216}function Tt(n,r,i){n[r]=i&255,n[r+1]=i>>>8&255,n[r+2]=i>>>16&255,n[r+3]=i>>>24&255}function ne(n,r,i){let a="";for(let o=0;o<i;o+=1)a+=String.fromCharCode(n[r+o]??0);return a}async function fn(n){let r=n.uploads.limits,i=n.uploads.images,a=st(n.bytes),o=Pt(n.contentType,a);if(It(o,r?.accept),r?.maxFileSize){let T=ee(r.maxFileSize,"uploads.limits.maxFileSize");if(n.bytes.byteLength>T)throw new e(`"${n.filename}" is ${Ot(n.bytes.byteLength)}, over the ${r.maxFileSize} limit`,{status:413,code:"file_too_large"})}let l=r?.maxImageDimensions;if(a&&l){if(a.width>l.width||a.height>l.height)throw new e(`"${n.filename}" is ${a.width}x${a.height}, over the ${l.width}x${l.height} limit`,{status:422,code:"image_too_large"})}let m=n.bytes,x=a,v=o;if(a&&i){let T=await _t(m,a,i,v);m=T.data,x=T.info,v=T.contentType}return{data:m,contentType:v,filename:le(n.filename),info:x,checksum:qe(await dt(m)),extension:at(v)}}async function _t(n,r,i,a){let o=i.processor,l={},m=i.convert;if(m&&!(m.keep??[]).includes(a)&&r.format!=="svg")l.format=m.to;let x=i.maxDimensions;if(x&&(r.width>x.width||r.height>x.height))l.width=x.width,l.height=x.height,l.fit="inside";if(i.quality!==void 0)l.quality=i.quality;if((l.format!==void 0||l.width!==void 0)&&o&&o.supports(a)){if(i.stripMetadata!==!1)l.stripMetadata=!0;let N=await o.transform(n,l,r);return{data:N.data,contentType:N.contentType,info:{format:r.format,contentType:N.contentType,width:N.width,height:N.height}}}return{data:i.stripMetadata===!0?ut(n,a):n,info:r,contentType:a}}function It(n,r){if(!r||r.length===0)return;if(r.some((i)=>fe(n,i)))return;throw new e(`"${n}" is not an accepted file type; uploads.limits.accept allows ${r.join(", ")}`,{status:415,code:"unsupported_media_type"})}function fe(n,r){let i=n.toLowerCase().split(";")[0]?.trim()??"",a=r.toLowerCase().trim();if(a==="*"||a==="*/*")return!0;if(a.endsWith("/*"))return i.startsWith(a.slice(0,-1));return i===a}function Pt(n,r){if(r)return r.contentType;let i=n.split(";")[0]?.trim().toLowerCase();return i&&i.includes("/")?i:"application/octet-stream"}function le(n){let i=(n.split(/[/\\]/).pop()??"file").replaceAll("\x00","").replace(/[\u0000-\u001f\u007f"]/g,"").trim();return i.length>0?i.slice(0,255):"file"}function Ot(n){if(n<1024)return`${n} B`;if(n<1048576)return`${(n/1024).toFixed(1)} kB`;return`${(n/1048576).toFixed(1)} MB`}var Dt=25,Rt=200,me=[u("created_at","desc"),u("id","desc")];function zt(n){let{config:r}=n,i,a=()=>{if(!r.uploads)throw new e("This CMS has no uploads configured; add an `uploads` section with a storage adapter.",{status:501,code:"uploads_not_configured"});return r.uploads},o=()=>(i??=Promise.resolve(typeof a().storage==="function"?a().storage():a().storage),i);async function l(f){let h=await n.database();return h.transaction((g)=>f(g,d(h,g)))}let m={config:r,database:n.database,storage:o,emit:n.emit,deliver:n.deliver},x=(f,h)=>{if(!r.rbac)return;if(P(f,`media:${h}`))return;throw f?e.forbidden(`Not allowed to ${h} media; the "media:${h}" permission is required`):e.unauthorized(`Not allowed to ${h} media`)},v=async(f,h,g,A,y={})=>{await n.emit(f,[{type:h,data:{media:se(g),...y},previous:null}],{actor:A,collection:"media",documentId:g.id})},T=async(f,h)=>{let g=await f.findOne(O,t("id",h));if(!g)throw e.notFound(`No media with id "${h}"`);return g};async function N(f){let h=a(),g=f.actor??null;x(g,"create");let A=await ye(f.file),y=await fn({bytes:A,filename:f.filename??Nt(f.file)??"file",contentType:f.contentType??Lt(f.file)??"application/octet-stream",uploads:h}),S=w("med"),_=await o(),C=$t(_,S,y.filename,y.extension);await _.put(C,y.data,{contentType:y.contentType,size:y.data.byteLength,cacheControl:"public, max-age=31536000, immutable"});let R=new Date,M;try{M=await l(async(E,J)=>{let F=await J.insert(O,{id:S,filename:y.filename,mime_type:y.contentType,size:y.data.byteLength,width:y.info?.width??null,height:y.info?.height??null,storage_key:C,checksum:y.checksum,alt:Jt(f.alt,f.locale??r.i18n.defaultLocale),focal_x:null,focal_y:null,status:"active",orphaned_at:null,purge_after:null,purge_error:null,metadata:{...f.metadata??{}},created_by:g?.id??null,created_at:R,updated_at:R}),V=L(F,_);return await v(E,"media.uploaded",V,g),V})}catch(E){throw await _.delete([C]).catch(()=>{return}),E}if(n.deliver(),h.images?.variants?.mode==="pregenerate")return Oe(M,g);return M}async function Oe(f,h){for(let g of X(a().images))try{let A=await he({id:f.id,variant:g});if(A)await Vt(A.body)}catch(A){await l((y)=>n.emit(y,[{type:"media.processing.failed",data:{media:se(f),variant:g,error:A instanceof Error?A.message:String(A)},previous:null}],{actor:h,collection:"media",documentId:f.id})),n.deliver()}return await ge(f.id)??f}async function De(f={}){let h=jt(f.limit),g=[];if(f.status)g.push(t("status",f.status));if(f.search)g.push(te("filename",`%${f.search}%`,!0));let A=f.mimeType?.includes("*")===!0?f.mimeType:null;if(f.mimeType&&!A)g.push(t("mime_type",f.mimeType));let y=g.length>0?s(...g):void 0,S=await n.database(),_=await S.transaction((F)=>S.query(F,{table:O,...f.cursor?{where:s(...y?[y]:[],q(f.cursor,me))}:y===void 0?{}:{where:y},orderBy:me,limit:h+1})),C=A?_.filter((F)=>fe(String(F.mime_type),A)):_,R=C.length>h,M=C.slice(0,h),E=await o(),J=M.at(-1);return{docs:M.map((F)=>L(F,E)),limit:h,hasNextPage:R,cursor:J?W(J,me):null}}async function ge(f){let h=await l((g,A)=>A.findOne(O,t("id",f)));return h?L(h,await o()):null}async function Re(f){return(await l((g,A)=>A.find(z,t("media_id",f)))).map((g)=>({mediaId:String(g.media_id),collection:String(g.collection),documentId:String(g.document_id),field:String(g.field),locale:String(g.locale??""),createdAt:c(g.created_at)}))}async function ke(f){let h=a(),g=f.actor??null;x(g,"update"),kt(h,f);let A=await o(),{media:y,stale:S}=await l(async(_,C)=>{let R=await T(C,f.id),M=L(R,A),J=f.crop!==void 0&&!Pe(f.crop,M.crop)||f.focalPoint!==void 0&&!Pe(f.focalPoint,M.focalPoint)?M.variants:[],F={updated_at:new Date};if(f.filename!==void 0)F.filename=le(f.filename);if(f.alt!==void 0)F.alt=Ft(M.alt,f.alt,f.locale??r.i18n.defaultLocale);if(f.focalPoint!==void 0)F.focal_x=f.focalPoint?.x??null,F.focal_y=f.focalPoint?.y??null;let V={...p(R.metadata),...f.metadata??{}};if(f.crop===null)delete V.crop;else if(f.crop!==void 0)V.crop={...f.crop};if(J.length>0)delete V.variants;F.metadata=V,await C.update(O,t("id",f.id),F);let H=L({...R,...F},A);await v(_,"media.updated",H,g);let Ee=Q(h.images,H.mimeType);return{media:H,stale:J.map((Ne)=>Me(H.storageKey,Ne,Ee))}});if(S.length>0)await A.delete(S).catch(()=>{return});return n.deliver(),y}async function $e(f){let h=f.actor??null;x(h,"update");let g=await l(async(A,y)=>{let S=await T(y,f.id);if(String(S.status)==="active")throw e.conflict(`"${f.id}" is in use; only an unused file has a deadline to clear`);let _={purge_after:null,purge_error:null,updated_at:new Date};await y.update(O,t("id",f.id),_);let C=L({...S,..._},await o());return await v(A,"media.updated",C,h,{kept:!0}),C});return n.deliver(),g}async function je(f){let h=f.actor??null;x(h,"delete");let g=await o(),{media:A,keys:y}=await l(async(S,_)=>{let C=await T(_,f.id),R=L(C,g);if(f.force!==!0){let M=await _.find(z,t("media_id",f.id));if(M.length>0){let E=M.slice(0,3).map((J)=>`${String(J.collection)}/${String(J.document_id)}`).join(", ");throw e.conflict(`"${R.filename}" is used by ${M.length} document${M.length===1?"":"s"} (${E}); pass force to delete it anyway`)}}return await _.delete(z,t("media_id",f.id)),await _.delete(O,t("id",f.id)),await v(S,"media.purged",R,h),{media:R,keys:ue(R,r.uploads)}});return await g.delete(y),n.deliver(),A}async function he(f){let h=a(),g=await o(),A=await l((E,J)=>J.findOne(O,t("id",f.id)));if(!A)return null;let y=L(A,g);if(!f.variant)return re(g,y,null);let S=h.images?.processor;if(!S||!S.supports(y.mimeType)){let E=Se(h.images,f.variant);return re(g,y,f.variant,E)}let _=Q(h.images,y.mimeType),C=Me(y.storageKey,f.variant,_);if(f.refresh!==!0){let E=await g.get(C);if(E){let J=await g.head?.(C);return{media:y,variant:f.variant,key:C,contentType:J?.contentType??_,width:null,height:null,size:J?.size??null,body:E,url:await pe(g,C),cached:!0}}}let R=await g.get(y.storageKey);if(!R)return null;let M=await Ce(S,await ye(R),mn(h.images,f.variant,y),y);if(!M)return re(g,y,f.variant);return await g.put(C,M.data,{contentType:M.contentType,size:M.data.byteLength,cacheControl:"public, max-age=31536000, immutable"}),await Je(y.id,f.variant),{media:y,variant:f.variant,key:C,contentType:M.contentType,width:M.width,height:M.height,size:M.data.byteLength,body:ct(M.data),url:await pe(g,C),cached:!1}}async function re(f,h,g,A=""){let y=await f.get(h.storageKey);if(!y)return null;let S=await pe(f,h.storageKey);return{media:h,variant:g,key:h.storageKey,contentType:h.mimeType,width:h.width,height:h.height,size:h.size,body:y,url:A?`${S}?${A}`:S,cached:g===null}}async function Je(f,h){await l(async(g,A)=>{let y=await A.findOne(O,t("id",f));if(!y)return;let S=p(y.metadata),_=Array.isArray(S.variants)?S.variants.filter((C)=>typeof C==="string"):[];if(_.includes(h))return;await A.update(O,t("id",f),{metadata:{...S,variants:[..._,h].sort()}})})}function Fe(f){return _e(m,f)}return{upload:N,list:De,get:ge,update:ke,delete:je,keep:$e,usages:Re,variant:he,collect:Fe,storage:o}}function kt(n,r){for(let i of Object.keys(r.metadata??{}))if(xe.includes(i))throw e.validation(`"${i}" is reserved inside media metadata; it is maintained by the engine`);if(r.focalPoint!==void 0&&n.images?.focalPoint!==!0)throw e.validation("Focal points are off; set uploads.images.focalPoint to true");if(r.crop!==void 0&&n.images?.crop!==!0)throw e.validation("Cropping is off; set uploads.images.crop to true");if(r.focalPoint&&!Et(r.focalPoint))throw e.validation("A focal point is relative: x and y are between 0 and 1")}function $t(n,r,i,a){let l=(n.prefix?.({id:r,filename:i})??String(new Date().getUTCFullYear())).replace(/^\/+|\/+$/g,"");return l?`${l}/${r}.${a}`:`${r}.${a}`}async function pe(n,r){return n.signedUrl?n.signedUrl(r):n.url(r)}function jt(n){if(n===void 0)return Dt;if(!Number.isInteger(n)||n<1)throw new e(`limit must be a positive integer, received ${n}`,{status:400,code:"invalid_pagination"});return Math.min(n,Rt)}function Jt(n,r){if(n===void 0)return{};return typeof n==="string"?{[r]:n}:{...n}}function Ft(n,r,i){return typeof r==="string"?{...n,[i]:r}:{...r}}function Et(n){return n.x>=0&&n.x<=1&&n.y>=0&&n.y<=1}function Nt(n){let r=n.name;return typeof r==="string"?r:void 0}function Lt(n){let r=n.type;return typeof r==="string"&&r.length>0?r:void 0}function Pe(n,r){return JSON.stringify(n??null)===JSON.stringify(r??null)}async function Vt(n){let r=n.getReader();for(;;){let{done:i}=await r.read();if(i)break}}
|
|
2
|
-
export{Ut,Wt,Ht,W,q,L,mo,st,at,mn,Me,Bt,ye,ct,qe,zn,dt,ut,fn,zt};
|
package/dist/index-y5mwknr9.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var N="cms_migrations";function e(u,i,a={}){return{name:u,type:i,nullable:a.default!==void 0?!1:a.nullable??!0,storage:"column",...a.default===void 0?{}:{default:a.default},...a.unique===void 0?{}:{unique:a.unique},...a.index===void 0?{}:{index:a.index},...a.array===void 0?{}:{array:a.array},...a.references===void 0?{}:{references:a.references}}}var l=()=>e("id","text",{nullable:!1,unique:!0}),n=()=>e("created_at","timestamp",{nullable:!1}),o=()=>e("updated_at","timestamp",{nullable:!1});function t(u,i,a={}){let d=i.map((c)=>({kind:"column",column:c})),r=a.unique===!0?"uniq":"idx";return{name:a.name??`${r}_${u}_${i.join("_")}`,table:u,targets:d,unique:a.unique===!0}}function s(u,i,a=[],d){return{name:u,columns:[...i].sort((r,c)=>r.name.localeCompare(c.name)),primaryKey:["id"],indexes:[...a].sort((r,c)=>r.name.localeCompare(c.name)),...d===void 0?{}:{documentColumn:d}}}function ze(){return[m(),_(),b(),f(),p(),x(),h(),y(),T(),g(),v(),k(),q(),S(),j(),w(),C()].sort((u,i)=>u.name.localeCompare(i.name))}function Ve(){return["cms_migrations",...ze().map((u)=>u.name)].sort()}function m(){return s("documents",[l(),e("collection","text",{nullable:!1}),e("data","json",{nullable:!1}),e("revision","integer",{nullable:!1,default:1}),e("scheduled_at","timestamp"),e("scheduled_patch","json"),e("deleted_at","timestamp"),e("purge_after","timestamp"),n(),o(),e("updated_by","text")],[t("documents",["collection"]),t("documents",["collection","deleted_at"]),t("documents",["collection","updated_at"]),t("documents",["scheduled_at"]),t("documents",["purge_after"])],"data")}function _(){return s("cms_users",[l(),e("email","text",{nullable:!1,unique:!0}),e("name","text"),e("password_hash","text"),e("two_factor_secret","text"),e("two_factor_enabled","boolean",{default:!1}),e("status","text",{nullable:!1,default:"active"}),e("roles","json",{nullable:!1,array:!0}),e("avatar_url","text"),e("locale","text"),e("last_login_at","timestamp"),n(),o()],[t("cms_users",["email"],{unique:!0})])}function b(){return s("cms_sessions",[l(),e("user_id","text",{nullable:!1,references:{table:"cms_users",column:"id",onDelete:"cascade"}}),e("token_hash","text",{nullable:!1,unique:!0}),e("ip","text"),e("user_agent","text"),e("expires_at","timestamp",{nullable:!1}),n()],[t("cms_sessions",["token_hash"],{unique:!0}),t("cms_sessions",["user_id"]),t("cms_sessions",["expires_at"])])}function f(){return s("cms_accounts",[l(),e("user_id","text",{nullable:!1,references:{table:"cms_users",column:"id",onDelete:"cascade"}}),e("provider","text",{nullable:!1}),e("provider_account_id","text",{nullable:!1}),e("email","text"),n(),o()],[t("cms_accounts",["provider","provider_account_id"],{unique:!0,name:"uniq_cms_accounts_provider_account"}),t("cms_accounts",["user_id"])])}function p(){return s("cms_tokens",[l(),e("type","text",{nullable:!1}),e("user_id","text",{references:{table:"cms_users",column:"id",onDelete:"cascade"}}),e("email","text"),e("token_hash","text",{nullable:!1,unique:!0}),e("data","json"),e("expires_at","timestamp",{nullable:!1}),e("consumed_at","timestamp"),n()],[t("cms_tokens",["token_hash"],{unique:!0}),t("cms_tokens",["user_id"]),t("cms_tokens",["type","expires_at"])])}function x(){return s("cms_api_keys",[l(),e("name","text",{nullable:!1}),e("user_id","text",{references:{table:"cms_users",column:"id",onDelete:"cascade"}}),e("key_hash","text",{nullable:!1,unique:!0}),e("prefix","text",{nullable:!1}),e("scopes","json",{nullable:!1,array:!0}),e("last_used_at","timestamp"),e("expires_at","timestamp"),e("revoked_at","timestamp"),n()],[t("cms_api_keys",["key_hash"],{unique:!0}),t("cms_api_keys",["user_id"])])}function h(){return s("cms_roles",[l(),e("name","text",{nullable:!1,unique:!0}),e("label","text"),e("permissions","json",{nullable:!1,array:!0}),n(),o()],[t("cms_roles",["name"],{unique:!0})])}function y(){return s("cms_ai_credentials",[l(),e("provider","text",{nullable:!1,unique:!0}),e("auth_type","text",{nullable:!1,default:"api-key"}),e("secret","text",{nullable:!1}),e("hint","text"),n(),o()],[t("cms_ai_credentials",["provider"],{unique:!0})])}function T(){return s("cms_ai_mutations",[l(),e("idempotency_key","text",{nullable:!1,unique:!0}),e("run_id","text",{nullable:!1}),e("collection","text"),e("document_id","text"),e("result","json"),n()],[t("cms_ai_mutations",["idempotency_key"],{unique:!0}),t("cms_ai_mutations",["run_id"])])}function g(){return s("cms_ai_plans",[l(),e("run_id","text",{nullable:!1}),e("actor_id","text"),e("kind","text",{nullable:!1}),e("summary","text",{nullable:!1}),e("operations","json",{nullable:!1}),e("status","text",{nullable:!1,default:"pending"}),e("result","json"),e("expires_at","timestamp",{nullable:!1}),e("approved_at","timestamp"),n()],[t("cms_ai_plans",["run_id"]),t("cms_ai_plans",["status","expires_at"])])}function v(){return s("media",[l(),e("filename","text",{nullable:!1}),e("mime_type","text",{nullable:!1}),e("size","bigint",{nullable:!1}),e("width","integer"),e("height","integer"),e("storage_key","text",{nullable:!1,unique:!0}),e("checksum","text"),e("alt","json"),e("focal_x","real"),e("focal_y","real"),e("status","text",{nullable:!1,default:"active"}),e("orphaned_at","timestamp"),e("purge_after","timestamp"),e("purge_error","text"),e("metadata","json"),e("created_by","text"),n(),o()],[t("media",["storage_key"],{unique:!0}),t("media",["status"]),t("media",["status","purge_after"])])}function k(){return s("media_usages",[l(),e("media_id","text",{nullable:!1,references:{table:"media",column:"id",onDelete:"cascade"}}),e("collection","text",{nullable:!1}),e("document_id","text",{nullable:!1}),e("field","text",{nullable:!1}),e("locale","text",{nullable:!1,default:""}),n()],[t("media_usages",["media_id"]),t("media_usages",["document_id"]),t("media_usages",["media_id","document_id","field","locale"],{unique:!0,name:"uniq_media_usages_reference"})])}function q(){return s("webhooks",[l(),e("url","text",{nullable:!1}),e("events","json",{nullable:!1,array:!0}),e("filters","json"),e("headers","json"),e("secret","text"),e("active","boolean",{nullable:!1,default:!0}),n(),o()],[t("webhooks",["active"])])}function S(){return s("webhook_deliveries",[l(),e("webhook_id","text",{nullable:!1,references:{table:"webhooks",column:"id",onDelete:"cascade"}}),e("event_id","text",{nullable:!1}),e("event_type","text",{nullable:!1}),e("status","text",{nullable:!1,default:"pending"}),e("attempt","integer",{nullable:!1,default:0}),e("request_body","json"),e("response_status","integer"),e("response_body","text"),e("error","text"),e("next_attempt_at","timestamp"),e("delivered_at","timestamp"),n()],[t("webhook_deliveries",["webhook_id","created_at"]),t("webhook_deliveries",["status","next_attempt_at"]),t("webhook_deliveries",["event_id"])])}function j(){return s("outbox",[l(),e("event_id","text",{nullable:!1,unique:!0}),e("type","text",{nullable:!1}),e("payload","json",{nullable:!1}),e("previous","json"),e("actor","json"),e("collection","text"),e("document_id","text"),e("status","text",{nullable:!1,default:"pending"}),e("attempts","integer",{nullable:!1,default:0}),e("available_at","timestamp",{nullable:!1}),e("processed_at","timestamp"),e("error","text"),n()],[t("outbox",["event_id"],{unique:!0}),t("outbox",["status","available_at"]),t("outbox",["document_id","created_at"])])}function w(){return s("activity",[l(),e("actor_id","text"),e("actor_source","text"),e("action","text",{nullable:!1}),e("source","text"),e("collection","text"),e("document_id","text"),e("locale","text"),e("changes","json"),e("ip","text"),n()],[t("activity",["collection","document_id"]),t("activity",["actor_id"]),t("activity",["created_at"])])}function C(){return s("jobs",[l(),e("type","text",{nullable:!1}),e("payload","json"),e("status","text",{nullable:!1,default:"pending"}),e("run_at","timestamp",{nullable:!1}),e("attempts","integer",{nullable:!1,default:0}),e("locked_at","timestamp"),e("locked_by","text"),e("completed_at","timestamp"),e("error","text"),n()],[t("jobs",["status","run_at"]),t("jobs",["type"])])}
|
|
2
|
-
export{N,ze,Ve};
|