directus-extension-storage-manager 1.4.2 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.js +1 -1
- package/dist/app.js +2 -2
- package/package.json +1 -1
package/dist/api.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Readable as e,Transform as t}from"node:stream";import n from"node:path";import{createRequire as r}from"node:module";import i from"node:fs";import{pathToFileURL as o,fileURLToPath as s}from"node:url";import a from"node:fs/promises";import{randomUUID as c}from"node:crypto";function l(e){return!(!e||"object"!=typeof e)&&!0===e.admin}let u=null;async function d(e){try{const t=await(import(e)),n=t?.getStorage||t?.default?.getStorage;if("function"==typeof n)return n}catch{}return null}async function f(e){if(!i.existsSync(e))return null;try{const t=r(n.join(process.cwd(),"package.json"))(e),i=t?.getStorage||t?.default?.getStorage;if("function"==typeof i)return i}catch{}try{return await d(o(e).href)}catch{return null}}async function p(){if(u)return u;const e=["@directus/api/dist/storage/index.js","@directus/api/storage/index.js","directus/dist/storage/index.js"];for(const t of e){const e=await d(t);if(e)return u=e,e}for(const e of function(){const e=process.cwd(),t=Array.from(new Set([e,n.resolve(e,".."),"/directus",n.dirname(process.execPath)].filter(Boolean))),r=["node_modules/@directus/api/dist/storage/index.js","node_modules/@directus/api/storage/index.js","node_modules/directus/dist/storage/index.js","node_modules/directus/storage/index.js"],i=[];for(const e of t)for(const t of r)i.push(n.join(e,t));return i}()){const t=await f(e);if(t)return u=t,t}throw new Error("Could not resolve Directus getStorage(). Ensure this extension runs inside the Directus API process (not sandboxed).")}async function g(){return(await p())()}async function m(e,t){if("function"==typeof e.read)return await e.read(t);if("function"==typeof e.getStream)return e.getStream(t);throw new Error("Storage disk does not support read/getStream")}async function h(e,t,n,r){if("function"!=typeof e.write){if("function"!=typeof e.put)throw new Error("Storage disk does not support write/put");await e.put(t,n,r||void 0)}else await e.write(t,n,r||void 0)}async function _(e,t){if("function"==typeof e.exists)return await e.exists(t);try{return await y(e,t),!0}catch{return!1}}async function y(e,t){if("function"==typeof e.stat){const n=await e.stat(t);return{size:Number(n.size)||0}}if("function"==typeof e.getStat){const n=await e.getStat(t);return{size:Number(n.size)||0}}throw new Error("Storage disk does not support stat/getStat")}async function w(e,t){if("function"!=typeof e.delete)throw new Error("Storage disk does not support delete");await e.delete(t)}async function*v(e,t=""){if("function"!=typeof e.list)throw new Error("Storage disk does not support list() — cannot detect orphan files on this driver");for await(const n of e.list(t))yield String(n)}const k=/__[a-f0-9]{16,}(?:\.[^.]+)?$/i;function S(e){const t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,""),r=n.posix.parse(t);return{dir:r.dir,stem:r.name}}function b(e,t){return e.startsWith(`${t}__`)&&k.test(e)}async function $(e,t){if("function"!=typeof e.list)return[];const{dir:r,stem:i}=S(t);if(!r)return[];const o=[];for await(const t of e.list(`${r}/${i}`)){const e=String(t||"").replace(/^[/\\]+/,""),s=n.posix.basename(e);n.posix.dirname(e)===r&&b(s,i)&&o.push(e)}return o}async function z(e,t){const n=await async function(e,t){if("function"!=typeof e.list)return[];const{stem:n}=S(t),r=[];for await(const t of e.list(n)){const e=String(t||"").replace(/^[/\\]+/,"");e.includes("/")||b(e,n)&&r.push(e)}return r}(e,t),r=await $(e,t);return[...new Set([...n,...r])]}async function j(e,t){const n=await z(e,t);for(const t of n)try{await w(e,t)}catch{}try{await w(e,t)}catch{}}const x={local:{id:"local",label:"Local Disk",short:"Local",icon:"hard_drive"},s3:{id:"s3",label:"Amazon S3",short:"S3",icon:"cloud"},gcs:{id:"gcs",label:"Google Cloud Storage",short:"GCS",icon:"cloud_queue"},azure:{id:"azure",label:"Azure Blob",short:"Azure",icon:"cloud_done"},cloudinary:{id:"cloudinary",label:"Cloudinary",short:"Cloudinary",icon:"photo_library"},supabase:{id:"supabase",label:"Supabase",short:"Supabase",icon:"storage"}};function A(e,t){const n=e[t];if(null==n)return null;const r=String(n).trim();return""===r?null:r}function E(e){const t=(n=e.STORAGE_LOCATIONS)?Array.isArray(n)?n.map(e=>String(e).trim()).filter(Boolean):String(n).split(",").map(e=>e.trim()).filter(Boolean):[];var n;return t.length>0?t:["local"]}function I(e,t){return A(e,`STORAGE_${t.toUpperCase()}_DRIVER`)||"local"}function O(e,t){return A(e,`STORAGE_${t.toUpperCase()}_ROOT`)}function P(e,t){return A(e,`STORAGE_${t.toUpperCase()}_BUCKET`)||A(e,`STORAGE_${t.toUpperCase()}_CONTAINER_NAME`)}async function N(e,t){const n=new Map;for(const e of t)n.set(e,{file_count:0,total_bytes:0});if(!t.length)return n;const r=await e("directus_files").whereIn("storage",t).select("storage").select(e.raw("count(*) as file_count"),e.raw("coalesce(sum(filesize), 0) as total_bytes")).groupBy("storage");for(const e of r||[])n.set(String(e.storage),{file_count:Number(e.file_count||0),total_bytes:Number(e.total_bytes||0)});return n}async function T(e,t,r,o){const s=I(e,r),{file_count:a,total_bytes:c}=o||await async function(e,t){return(await N(e,[t])).get(t)||{file_count:0,total_bytes:0}}(t,r);let l={disk_total_bytes:null,disk_free_bytes:null,disk_used_bytes:null,disk_used_percent:null,disk_available:!1};return"local"===s&&(l=await async function(e){const t={disk_total_bytes:null,disk_free_bytes:null,disk_used_bytes:null,disk_used_percent:null,disk_available:!1};if(!e)return t;const r=process.env.PWD||process.cwd()||"/directus",o=n.isAbsolute(e)?e:n.join(r,e);try{if(!i.existsSync(o))return t;const e=i.promises.statfs;if("function"==typeof e){const t=await e(o),n=Number(t.bsize||t.frsize||0),r=n*Number(t.blocks||0),i=n*Number(t.bavail??t.bfree??0),s=Math.max(0,r-i);return{disk_total_bytes:r||null,disk_free_bytes:i||null,disk_used_bytes:s||null,disk_used_percent:r>0?s/r*100:null,disk_available:r>0}}}catch{}return t}(O(e,r))),{location:r,driver:s,file_count:a,total_bytes:c,...l}}async function Z(e,t,n,r){const i=await T(e,t,n,r),o=function(e){const t=String(e||"local").toLowerCase();return x[t]||{id:t,label:t,short:t.slice(0,8).toUpperCase(),icon:"storage"}}(i.driver);return{...i,label:o.label,short:o.short,icon:o.icon,root:O(e,n),bucket:P(e,n),folder_count:0,mirror_directus_folders:!1}}const C="storage_manager",F=".keep",D={prefix_strategy:"none",folder_sync_enabled:!1,folder_sync_rename:"full_sync",folder_sync_delete:"move_to_parent",type_map:{image:"images",video:"videos",audio:"audio",text:"documents"},date_format:"yyyy/MM"};function B(e){return String(e||"").replace(/\\/g,"/").replace(/^\/+|\/+$/g,"").replace(/\/+/g,"/")}function U(...e){return e.map(e=>B(e)).filter(Boolean).join("/")}function R(e,t,r,i=!1){const o=B(t),s=B(e);if(i)return s?o?`${o}/${s}`:s:o;const a=(r||[]).map(e=>B(e)).filter(Boolean).sort((e,t)=>t.length-e.length);for(const e of a)if(s===e||s.startsWith(`${e}/`)){const t=n.posix.basename(e),r=s===e?"":s.slice(e.length+1),i=r?`${t}/${r}`:t;return o?`${o}/${i}`:i}const c=n.posix.basename(s);return o?`${o}/${c}`:c}function M(e){return n.basename(e)===F}function q(e,t){const r=process.env.PWD||process.cwd()||"/directus",i=n.isAbsolute(e)?e:n.join(r,e),o=n.resolve(i,t);if(!o.startsWith(n.resolve(i)))throw new Error("Invalid storage path");return o}function L(e){const t=String(e||"").trim();if(!t)throw new Error("Folder name is required");if(t.includes("/")||t.includes("\\"))throw new Error("Folder name cannot contain slashes");if("."===t||".."===t||t===F)throw new Error("Invalid folder name");return t}async function W(e,t,n){const r=new Set,i=I(n,e),o=O(n,e),s=B(t);if("local"===i&&o){const e=q(o,s||".");try{const t=await a.readdir(e,{withFileTypes:!0});for(const e of t)e.isDirectory()&&e.name&&!e.name.startsWith(".")&&r.add(e.name)}catch{}return r}try{const t=(await g()).location(e),n=s?`${s}/`:"";for await(const e of v(t,n)){const t=String(e||"").replace(/^[/\\]+/,"");if(!t.startsWith(n)&&n)continue;const i=n?t.slice(n.length):t,o=i.split("/")[0];o&&!o.startsWith(".")&&(i.includes("/")?r.add(o):M(t))}}catch{}return r}async function J(e,t,n){const r=B(n),i=r?`${r}/`:"",o=String(e?.client?.config?.client||e?.client?.driverName||e?.client?.dialect||"").toLowerCase(),s=i.length+1;try{let n=[];const r=e("directus_files").where("storage",t).whereNotNull("filename_disk");if(i?r.where("filename_disk","like",`${i}%`):r.where("filename_disk","like","%/%"),o.includes("pg")||o.includes("cockroach")){const t=i?`substring(filename_disk from ${s})`:"filename_disk";n=await r.whereRaw(`${t} like ?`,["%/%"]).select(e.raw(`DISTINCT split_part(${t}, '/', 1) as segment`))}else if(o.includes("mysql")||o.includes("maria")){const t=i?`SUBSTRING(filename_disk, ${s})`:"filename_disk";n=await r.whereRaw(`${t} like ?`,["%/%"]).select(e.raw(`DISTINCT SUBSTRING_INDEX(${t}, '/', 1) as segment`))}else if(o.includes("sqlite")){const t=i?`substr(filename_disk, ${s})`:"filename_disk";n=await r.whereRaw(`instr(${t}, '/') > 0`).select(e.raw(`DISTINCT substr(${t}, 1, instr(${t}, '/') - 1) as segment`))}else{if(!o.includes("mssql"))return new Set;{const t=i?`SUBSTRING(filename_disk, ${s}, 4000)`:"filename_disk";n=await r.whereRaw(`CHARINDEX('/', ${t}) > 0`).select(e.raw(`DISTINCT LEFT(${t}, CHARINDEX('/', ${t}) - 1) as segment`))}}const a=new Set;for(const e of n){const t=String(e.segment||"").trim();!t||t.startsWith(".")||t.includes("/")||t.includes("\\")||a.add(t)}return a}catch{return new Set}}async function G(e,t,r){const i=new Set;if("local"===I(r,e))return i;const o=B(t),s=o?`${o}/`:"";try{const t=(await g()).location(e);for await(const e of v(t,s)){const t=String(e||"").replace(/^[/\\]+/,"");if(!M(t))continue;const r=B(n.posix.dirname(t));if(o){if(r===o)continue;if(!r.startsWith(`${o}/`))continue;const e=r.slice(o.length+1).split("/")[0];e&&!e.startsWith(".")&&i.add(e)}else{const e=r.split("/").filter(Boolean);1===e.length&&i.add(e[0])}}}catch{}return i}async function H(e,t,n,r){const i=B(n),o=new Set;for(const n of await J(e,t,i))o.add(n);for(const e of await W(t,i,r))o.add(e);for(const e of await G(t,i,r))o.add(e);const s=Array.from(o).sort((e,t)=>e.localeCompare(t)).map(e=>({name:e,path:U(i,e)}));return{path:i,folders:s}}function V(e,t){const n=B(t).split("/").filter(Boolean);for(let t=1;t<=n.length;t++)e.add(n.slice(0,t).join("/"))}async function K(e,t,r){const i=new Set;for(const r of await async function(e,t){const r=new Set,i=await e("directus_files").select("filename_disk").where("storage",t);for(const e of i){const t=String(e.filename_disk||"").replace(/^[/\\]+/,"");if(!t||M(t))continue;const i=B(n.posix.dirname(t));i&&"."!==i&&V(r,i)}return r}(e,t))i.add(r);for(const e of await async function(e,t){const n=new Set,r=I(t,e),i=O(t,e);return"local"===r&&i?(await async function e(t){const r=q(i,t||".");let o;try{o=await a.readdir(r,{withFileTypes:!0})}catch{return}for(const r of o){if(!r.isDirectory()||!r.name||r.name.startsWith("."))continue;const i=U(t,r.name);n.add(i),await e(i)}}(""),n):n}(t,r))i.add(e);for(const e of await async function(e,t){const r=new Set;if("local"===I(t,e))return r;try{const t=(await g()).location(e);for await(const e of v(t,"")){const t=String(e||"").replace(/^[/\\]+/,"");if(!M(t))continue;const i=B(n.posix.dirname(t));i&&"."!==i&&V(r,i)}}catch{}return r}(t,r))i.add(e);return Array.from(i)}function X(e,t,n){const r=B(e);if(!r)return"";if(null==t)return r;if(n?.length)return R(`${r}/__folder__`,t,n).replace(/\/__folder__$/,"");const i=B(t);return i?`${i}/${r}`:r}async function Y(e,t,n){const r=B(t);if(!r)return;let i="";for(const t of r.split("/").filter(Boolean))await te(e,t,i,n),i=U(i,t)}async function Q(e,t,n){const r=B(t);if(!r)return;if("local"===I(n,e)){const t=O(n,e);if(!t)return;const i=q(t,r);try{await a.rm(i,{recursive:!0,force:!0})}catch{}return}try{const t=(await g()).location(e),n=`${r}/${F}`;await _(t,n)&&await w(t,n)}catch{}}async function ee(e){let t=await async function(e,t,r){const i=await K(e,t,r),o=new Set,s=await e("directus_files").select("filename_disk").where("storage",t);for(const e of s){const t=String(e.filename_disk||"").replace(/^[/\\]+/,"");if(!t||M(t))continue;const r=B(n.posix.dirname(t));r&&"."!==r&&V(o,r)}return i.filter(e=>!o.has(e))}(e.database,e.sourceLocation,e.env);t=function(e,t,n){if(t?.length){const n=t.map(e=>B(e)).filter(Boolean);return e.filter(e=>n.some(t=>e===t||e.startsWith(`${t}/`)))}if(n){const t=B(n);return t?e.filter(e=>e===t||e.startsWith(`${t}/`)):e}return e}(t,e.sourceFolders,e.sourcePath),t.sort((e,t)=>e.length-t.length);let r=0;for(const n of t){const t=X(n,e.targetPath,e.sourceFolders);if(t)try{await Y(e.targetLocation,t,e.env),r+=1}catch(t){e.logger?.warn(`[storage-manager] Failed copying empty folder ${n}: ${t?.message||t}`)}}if(e.removeSource&&r)for(const n of[...t].sort((e,t)=>t.length-e.length))try{await Q(e.sourceLocation,n,e.env),await ie(e.sourceLocation,`${n}/.keep`,e.env)}catch{}return r}async function te(t,n,r,i){const o=U(r,L(n));if("local"===I(i,t)){const e=O(i,t);if(!e)throw new Error(`Local storage “${t}” has no STORAGE_${t.toUpperCase()}_ROOT`);const n=q(e,o);return await a.mkdir(n,{recursive:!0}),{path:o}}const s=(await g()).location(t),c=`${o}/${F}`;if(!await _(s,c)){const t=e.from([Buffer.alloc(0)]);await h(s,c,t,"application/octet-stream")}return{path:o}}async function ne(e,t,n,r,i,o,s,a=!1){const c=(await g()).location(t),l=[],u=await e("directus_files").select("id","storage","filename_disk","type").where("storage",t).whereIn("id",n.map(String));for(const n of u){const u=String(n.id),d=String(n.filename_disk||""),f=R(d,r,s,a);if(d&&d!==f)try{if(!await _(c,d))throw new Error("Source object missing on storage");if(await e("directus_files").select("id").where({storage:t,filename_disk:f}).whereNot({id:u}).first()){l.push({id:u,from:d,to:f,status:"skipped",error:"Destination already has a file at this path — left in place"});continue}if(!await _(c,f)){const e=await m(c,d);if(await h(c,f,e,n.type),!await _(c,f))throw new Error("Write verification failed")}try{const e=await $(c,d);for(const t of e)try{await w(c,t)}catch{}}catch{}await w(c,d),await e("directus_files").where("id",u).update({filename_disk:f}),await ie(t,d,o),l.push({id:u,from:d,to:f,status:"moved"}),i?.info(`[storage-manager] Moved ${d} → ${f} on ${t}`)}catch(e){l.push({id:u,from:d,to:f,status:"failed",error:e?.message||String(e)}),i?.warn(`[storage-manager] Move failed for ${u}: ${e?.message}`)}else l.push({id:u,from:d,to:f,status:"moved"})}return{moved:l.filter(e=>"moved"===e.status).length,failed:l.filter(e=>"failed"===e.status).length,skipped:l.filter(e=>"skipped"===e.status).length,results:l}}function re(e){const t=B(e),n=t.lastIndexOf("/");return-1===n?"":t.slice(0,n)}async function ie(e,t,n){if(!n||"local"!==I(n,e))return;const r=O(n,e);if(!r)return;let i=re(t);for(;i;){const e=q(r,i);try{if((await a.readdir(e)).length>0)return;await a.rmdir(e)}catch{return}i=re(i)}}async function oe(t,r,i,o,s,c){const l=B(i),u=B(o);if(!l)throw new Error("Source folder path is required");if(!u)throw new Error("Destination folder path is required");if(l===u)return{path:u,moved:0,failed:0};if(u.startsWith(`${l}/`))throw new Error("Cannot move a folder into itself");if(L(n.posix.basename(u)),await async function(e,t,r,i){const o=B(r);if(!o)return!1;if(await e("directus_files").select("id").where("storage",t).whereRaw("filename_disk LIKE ?",[`${o}/%`]).first())return!0;const s=re(o),a=n.posix.basename(o),c=new Set;for(const n of await J(e,t,s))c.add(n);for(const e of await W(t,s,i))c.add(e);for(const e of await G(t,s,i))c.add(e);return c.has(a)}(t,r,u,s))throw new Error(`Folder already exists: ${u}`);const{moved:d,failed:f}=await se(t,r,l,u,c);if(f>0)throw new Error(`Failed to relocate ${f} file(s) under ${l}`);if("local"===I(s,r)){const e=O(s,r);if(!e)throw new Error(`Local storage “${r}” has no STORAGE_${r.toUpperCase()}_ROOT`);const t=q(e,l),i=q(e,u);await a.mkdir(n.dirname(i),{recursive:!0});try{await a.access(t);try{await a.access(i);const e=await a.readdir(t,{withFileTypes:!0});for(const r of e){const e=n.join(t,r.name),o=n.join(i,r.name);try{await a.rename(e,o)}catch{}}await a.rm(t,{recursive:!0,force:!0})}catch{await a.rename(t,i)}}catch{await a.mkdir(i,{recursive:!0})}}else{const t=(await g()).location(r),n=`${l}/`;try{for await(const e of v(t,n)){const r=String(e||"").replace(/^[/\\]+/,"");if(!r.startsWith(n))continue;const i=u+r.slice(l.length);try{if(await _(t,i)){await w(t,r);continue}const e=await m(t,r);await h(t,i,e,"application/octet-stream"),await w(t,r)}catch(e){c?.warn(`[storage-manager] Folder leftover move failed ${r}: ${e?.message}`)}}}catch{}const i=`${u}/${F}`;if(!await _(t,i)){const n=e.from([Buffer.alloc(0)]);await h(t,i,n,"application/octet-stream")}const o=`${l}/${F}`;if(await _(t,o))try{await w(t,o)}catch{}}return c?.info(`[storage-manager] Relocated folder ${l} → ${u} on ${r} (${d} file(s))`),{path:u,moved:d,failed:f}}async function se(e,t,n,r,i){const o=B(n),s=B(r);if(!o||o===s)return{moved:0,failed:0};const a=await e("directus_files").select("id","filename_disk","type").where("storage",t).whereRaw("filename_disk LIKE ?",[`${o}/%`]);if(!a.length)return{moved:0,failed:0};const c=(await g()).location(t);let l=0,u=0;for(const n of a){const r=String(n.id),a=String(n.filename_disk||"");if(!a.startsWith(`${o}/`))continue;if(M(a))continue;const d=a.slice(o.length).replace(/^\//,""),f=s?`${s}/${d}`:d;try{if(a===f){l++;continue}if(!await _(c,a)){await e("directus_files").where("id",r).update({filename_disk:f}),l++,i?.warn(`[storage-manager] Prefix relocate DB-only (missing source): ${a} → ${f}`);continue}if(await _(c,f))throw new Error(`Target already exists: ${f}`);const o=await m(c,a);if(await h(c,f,o,n.type),!await _(c,f))throw new Error("Write verification failed");try{const e=await $(c,a);for(const t of e)try{await w(c,t)}catch{}}catch{}await w(c,a),await e("directus_files").where("id",r).update({filename_disk:f}),l++,i?.info(`[storage-manager] Prefix relocate ${a} → ${f} on ${t}`)}catch(e){u++,i?.warn(`[storage-manager] Prefix relocate failed for ${r}: ${e?.message}`)}}return{moved:l,failed:u}}function ae(e){return String(e.title||e.filename_download||e.filename_disk||e.id)}async function ce(e,t,n,r){await j(e,t.filename_disk);try{await ie(t.storage,t.filename_disk,n)}catch(e){r?.warn?.(`[storage-manager] Failed pruning empty folders after ${t.filename_disk}: ${e instanceof Error?e.message:String(e)}`)}}async function le(e,t,n,r){const i=new Array(e.length);let o=0;const s=Array.from({length:Math.min(t,e.length)||1},()=>async function(){for(;o<e.length;){if(r?.())return;const t=o++;i[t]=await n(e[t],t)}}());return await Promise.all(s),i}async function ue(e,t,r,i){let o;try{o=await z(e,r)}catch(e){return void i?.warn?.(`[storage-manager] Could not list asset transforms for ${r}: ${e instanceof Error?e.message:String(e)}`)}for(const r of o)try{const i=n.posix.basename(r);if(await _(t,i))continue;const o=await m(e,r);await h(t,i,o,null)}catch(e){i?.warn?.(`[storage-manager] Failed copying asset transform ${r}: ${e instanceof Error?e.message:String(e)}`)}}async function de(e,n,r,i,o,s,a,c=!1,l){const u={id:e.id,filename_disk:a||e.filename_disk,from:e.storage,to:n,status:"failed"};if(!e.filename_disk)return{...u,status:"failed",error:"Missing filename_disk"};const d=String(a||e.filename_disk||"");if(e.storage===n&&d===e.filename_disk)return{...u,status:"skipped",error:"Already on target storage"};const f=await g(),p=f.location(e.storage),w=f.location(n);if(!await _(p,e.filename_disk))return{...u,status:"failed",error:`Source object missing on ${e.storage}`};if(await i("directus_files").select("id").where({storage:n,filename_disk:d}).whereNot({id:e.id}).first())return{...u,status:"skipped",error:"Destination already has a file at this path — left in place"};if(await _(w,d)){if(await ue(p,w,e.filename_disk,o),await i("directus_files").where({id:e.id}).update({storage:n,filename_disk:d}),"move"===r&&!c)try{await ce(p,e,l,o)}catch(t){o?.warn?.(`[storage-manager] DB updated but failed deleting source ${e.id}: ${t instanceof Error?t.message:String(t)}`)}const t=await y(w,d).catch(()=>({size:Number(e.filesize)||0}));return s&&t.size>0&&s(t.size),{...u,status:"move"===r?"moved":"copied",bytes:t.size}}const v=await m(p,e.filename_disk),k=s?v.pipe((S=s,new t({transform(e,t,n){const r=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e);r>0&&S(r),n(null,e)}}))):v;var S;try{await h(w,d,k,e.type)}catch(e){try{await _(w,d)&&await j(w,d)}catch{}return{...u,status:"failed",error:`Write failed: ${e instanceof Error?e.message:String(e)}`}}if(!await _(w,d))return{...u,status:"failed",error:"Target write did not persist (exists check failed)"};let b=0;try{b=(await y(w,d)).size}catch(e){return{...u,status:"failed",error:`Target stat failed after write: ${e instanceof Error?e.message:String(e)}`}}if(null!=e.filesize&&Number(e.filesize)>0&&b>0){const t=Number(e.filesize);if(Math.abs(t-b)>Math.max(64,.01*t)&&b<.95*t){try{await j(w,d)}catch{}return{...u,status:"failed",error:`Size mismatch after write (expected ~${t}, got ${b})`}}}await ue(p,w,e.filename_disk,o);try{await i("directus_files").where({id:e.id}).update({storage:n,filename_disk:d})}catch(e){try{await j(w,d)}catch{}return{...u,status:"failed",error:`DB update failed: ${e instanceof Error?e.message:String(e)}`}}if("move"===r&&!c)try{await ce(p,e,l,o)}catch(t){return o?.warn?.(`[storage-manager] Moved ${e.id} to ${n} but source delete failed: ${t instanceof Error?t.message:String(t)}`),{...u,status:"moved",bytes:b,error:`Moved, but source cleanup failed: ${t instanceof Error?t.message:String(t)}`}}return{...u,status:"move"===r?"moved":"copied",bytes:b}}async function fe(e){const{fileIds:t,targetStorage:n,mode:r,database:i,logger:o,onProgress:s,isCancelled:a,keepSourceFileOnDisk:c,targetPath:l,sourceFolders:u,preservePaths:d,includeEmptyFolders:f,sourceStorage:p,sourcePath:g,env:m}=e,h=Math.min(8,Math.max(1,Number(e.concurrency)||3)),_=Date.now(),y=Array.from(new Set(t.filter(Boolean)));async function w(e){if(!f||!m||a?.())return;const t=p||e||null;if(t&&t!==n)try{await ee({database:i,sourceLocation:t,targetLocation:n,env:m,targetPath:l,sourceFolders:u,sourcePath:g,removeSource:"move"===r&&!c,logger:o})}catch(e){o?.warn?.(`[storage-manager] Empty folder copy failed: ${e instanceof Error?e.message:String(e)}`)}}if(0===y.length){await w(null);const e={mode:r,target_storage:n,total:0,succeeded:0,skipped:0,failed:0,results:[],transferred_bytes:0,total_bytes:0,elapsed_ms:0};return s?.({type:"done",data:e}),e}const v=await i("directus_files").select("id","storage","filename_disk","filename_download","title","type","filesize").whereIn("id",y),k=new Map(v.map(e=>[String(e.id),e])),S=v.reduce((e,t)=>e+(Number(t.filesize)||0),0),b=v.length&&v.every(e=>e.storage===v[0].storage)?v[0].storage:null;s?.({type:"start",mode:r,from:b,to:n,total:y.length,total_bytes:S});let $=0,z=0,j=0,x=0,A=0;const E=new Map;let I=0;const O=await le(y,h,async e=>{if(a?.())return{id:e,filename_disk:"",from:"",to:n,status:"failed",error:"Cancelled"};const t=k.get(e),f=++A;if(!t){x+=1;const t={id:e,filename_disk:"",from:"",to:n,status:"failed",error:"File not found"};return s?.({type:"file_done",index:f,total:y.length,result:t,name:e,succeeded:z,skipped:j,failed:x,transferred_bytes:$,total_bytes:S,elapsed_ms:Date.now()-_}),t}let p;s?.({type:"file_start",index:f,total:y.length,id:t.id,name:ae(t),filename_disk:t.filename_disk,from:t.storage,to:n,bytes:Number(t.filesize)||0}),E.set(t.id,0);try{p=await de(t,n,r,i,o,e=>((e,t,n)=>{$+=n;const r=(E.get(t.id)||0)+n;E.set(t.id,r);const i=Date.now();i-I<120||(I=i,s?.({type:"file_bytes",index:e,id:t.id,file_transferred:r,file_bytes:Number(t.filesize)||0,transferred_bytes:$,total_bytes:S,elapsed_ms:i-_}))})(f,t,e),null!=l?function(e,t,n,r=!1){return R(e,t,n,r)}(t.filename_disk,l,u,d):void 0,Boolean(c),m)}catch(e){p={id:t.id,filename_disk:t.filename_disk,from:t.storage,to:n,status:"failed",error:e instanceof Error?e.message:String(e)}}if("moved"===p.status||"copied"===p.status){z+=1;const e=E.get(t.id)||0,n=Number(p.bytes)||Number(t.filesize)||0;n>e&&($+=n-e,E.set(t.id,n))}else"skipped"===p.status?j+=1:x+=1;return s?.({type:"file_done",index:f,total:y.length,result:p,name:ae(t),succeeded:z,skipped:j,failed:x,transferred_bytes:$,total_bytes:S,elapsed_ms:Date.now()-_}),p},a);await w(b);const P={mode:r,target_storage:n,total:O.filter(Boolean).length,succeeded:z,skipped:j,failed:x,results:O.filter(Boolean),transferred_bytes:$,total_bytes:S,elapsed_ms:Date.now()-_};return o?.info?.(`[storage-manager] ${r} → ${n}: ${z} ok, ${j} skipped, ${x} failed (of ${P.total})`),s?.({type:"done",data:P}),P}const pe=new Set(["image/jpeg","image/jpg","image/png","image/webp","image/gif","image/tiff","image/tif","image/avif"]);let ge;function me(e){if(!e)return!1;const t=e.toLowerCase();return"image/svg+xml"!==t&&(pe.has(t)||t.startsWith("image/"))}async function he(e){const t=await async function(){if(void 0!==ge)return ge;try{const e=r(n.join(process.cwd(),"package.json"))("sharp"),t="function"==typeof e?e:e?.default;if("function"==typeof t)return ge=t,ge}catch{}try{const e=await(import("sharp")),t="function"==typeof e.default?e.default:e;if("function"==typeof t)return ge=t,ge}catch{}return ge=null,null}();if(!t)return null;try{const n=await t(e,{failOn:"none"}).metadata();let r=n.width??0,i=n.height??0;if(n.orientation&&n.orientation>=5){const e=r;r=i,i=e}if(r>0&&i>0)return{width:r,height:i}}catch{}return null}async function _e(e,t){let n,r;try{n=await m(e,t)}catch{return null}try{r=await async function(e,t){const n=[];let r=0;try{for await(const i of e){const e=Buffer.isBuffer(i)?i:Buffer.from(i);if(n.push(e),r+=e.length,r>=t)break}}finally{!function(e){try{const t=e;"function"==typeof t.destroy&&t.destroy()}catch{}}(e)}const i=Buffer.concat(n);return i.length>t?i.subarray(0,t):i}(n,2097152)}catch{return null}return r.length?await he(r)||function(e){return function(e){if(e.length<24)return null;if(137!==e[0]||"PNG"!==e.toString("ascii",1,4))return null;const t=e.readUInt32BE(16),n=e.readUInt32BE(20);return t>0&&n>0?{width:t,height:n}:null}(e)||function(e){if(e.length<10||255!==e[0]||216!==e[1])return null;let t=2;for(;t+8<e.length;){if(255!==e[t]){t+=1;continue}const n=e[t+1];if(216===n||217===n||n>=208&&n<=215){t+=2;continue}if(1===n){t+=2;continue}if(n>=192&&n<=195||n>=197&&n<=199||n>=201&&n<=203||n>=205&&n<=207){const n=e.readUInt16BE(t+5),r=e.readUInt16BE(t+7);return r>0&&n>0?{width:r,height:n}:null}if(t+4>e.length)return null;const r=e.readUInt16BE(t+2);if(r<2)return null;t+=2+r}return null}(e)||function(e){if(e.length<10)return null;const t=e.toString("ascii",0,6);if("GIF87a"!==t&&"GIF89a"!==t)return null;const n=e.readUInt16LE(6),r=e.readUInt16LE(8);return n>0&&r>0?{width:n,height:r}:null}(e)||function(e){if(e.length<30)return null;if("RIFF"!==e.toString("ascii",0,4)||"WEBP"!==e.toString("ascii",8,12))return null;const t=e.toString("ascii",12,16);if("VP8X"===t){const t=1+e[24]+(e[25]<<8)+(e[26]<<16),n=1+e[27]+(e[28]<<8)+(e[29]<<16);return t>0&&n>0?{width:t,height:n}:null}if("VP8 "===t&&157===e[23]&&1===e[24]&&42===e[25]){const t=16383&e.readUInt16LE(26),n=16383&e.readUInt16LE(28);return t>0&&n>0?{width:t,height:n}:null}if("VP8L"===t&&e.length>=25&&47===e[20]){const t=e.readUInt32LE(21),n=1+(16383&t),r=1+(t>>14&16383);if(n>0&&r>0)return{width:n,height:r}}return null}(e)}(r):null}const ye=/__[a-f0-9]{16,}(?:\.[^.]+)?$/i;function we(e){return ye.test(n.basename(String(e||"")))}function ve(e){const t=String(e||"").replace(/^[/\\]+/,"");return Boolean(t)&&!t.includes("/")}function ke(e){return ve(e)&&we(e)}function Se(e,t){const n=String(t||"").trim().toLowerCase();return!n||String(e||"").toLowerCase().includes(n)}function be(e){const t=n.basename(e);return!(t&&!t.startsWith("."))||("directus-health-file"===t||!!we(e))}const $e={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".avif":"image/avif",".svg":"image/svg+xml",".pdf":"application/pdf",".mp4":"video/mp4",".webm":"video/webm",".mov":"video/quicktime",".mp3":"audio/mpeg",".wav":"audio/wav",".json":"application/json",".txt":"text/plain",".csv":"text/csv",".zip":"application/zip"};function ze(e){const t=n.extname(e).toLowerCase();return $e[t]||null}function je(e){const t=n.parse(n.basename(e)).name;return t.replace(/_/g," ").replace(/\s+/g," ").trim()||t||e}function xe(e){const t=n.parse(n.basename(e)).name;return/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(t)?t.toLowerCase():null}async function Ae(e,t){const r=new Set;if(t){const i=I(t,e),o=O(t,e);if("local"===i&&o){for(const e of await async function(e){const t=n.isAbsolute(e)?e:n.join(process.cwd(),e),r=[];return await async function e(t,i=""){let o;try{o=await a.readdir(t,{withFileTypes:!0})}catch{return}for(const s of o){const o=i?`${i}/${s.name}`:s.name;s.isDirectory()?await e(n.join(t,s.name),o):s.isFile()&&(be(o)||r.push(o))}}(t),r}(o))r.add(e);return Array.from(r)}}const i=(await g()).location(e);try{for await(const e of v(i,"")){const t=String(e||"").replace(/^[/\\]+/,"");t&&!be(t)&&r.add(t)}}catch(t){throw new Error(`Could not list files on storage “${e}”: ${t?.message||t}`)}return Array.from(r)}async function Ee(e,t,r,i){const o=String(i||"").replace(/\\/g,"/").replace(/^\/+|\/+$/g,"").replace(/\/+/g,"/"),s=await Ae(t,r),a=o?s.filter(e=>e===o||e.startsWith(`${o}/`)):s,c=await e("directus_files").select("filename_disk").where("storage",t),l=new Set(c.map(e=>String(e.filename_disk||"")).filter(Boolean)),u=(await g()).location(t),d=[];for(const e of a){if(l.has(e))continue;let t=0;try{const n=await y(u,e);t=Number(n.size)||0}catch{t=0}d.push({filename_disk:e,filesize:t,type:ze(e),suggested_id:xe(e),filename_download:n.basename(e),title:je(e)})}return d.sort((e,t)=>e.filename_disk.localeCompare(t.filename_disk)),{orphans:d,scanned:a.length,known:l.size,path:o}}const Ie={on_deselect:"keep",on_item_delete:"keep",scan_min_age_minutes:60,scan_text_fields:!0};function Oe(e){const t=e&&"object"==typeof e?e:{},n=t.on_deselect,r=t.on_item_delete,i=Number(t.scan_min_age_minutes);return{on_deselect:"ask"===n||"delete_if_unreferenced"===n||"keep"===n?n:Ie.on_deselect,on_item_delete:"delete_if_unreferenced"===r||"keep"===r?r:Ie.on_item_delete,scan_min_age_minutes:Number.isFinite(i)&&i>=0?Math.min(43200,Math.floor(i)):Ie.scan_min_age_minutes,scan_text_fields:void 0===t.scan_text_fields?Ie.scan_text_fields:Boolean(t.scan_text_fields)}}let Pe=null;function Ne(){Pe=null}async function Te(e){if(Pe)return Pe;try{if(!await e.schema.hasColumn("directus_settings",C))return Pe={locations:{}},Pe;const t=await e("directus_settings").select(C).first(),n=t?.[C],r="string"==typeof n?JSON.parse(n):n??{},i={locations:r.locations??{}};return r&&"object"==typeof r&&"name_mirror_claims"in r&&(i.name_mirror_claims=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return{};const t={};for(const[n,r]of Object.entries(e))"string"==typeof n&&n&&"string"==typeof r&&r&&(t[n]=r);return t}(r.name_mirror_claims)),r&&"object"==typeof r&&"lifecycle"in r&&(i.lifecycle=Oe(r.lifecycle)),Pe=i,Pe}catch(e){if(function(e){const t=String(e?.message||e||"");return/does not exist|unknown column|no such column/i.test(t)}(e))return Pe={locations:{}},Pe;throw e}}async function Ze(e,t){await e("directus_settings").update({[C]:JSON.stringify(t)}),Pe=t}function Ce(e,t){return{...D,...e.locations[t]??{}}}async function Fe(e,t,n,r){try{const i=await e.schema.hasColumn("directus_settings",C);if(i)return;const o=await n(),s=new t.FieldsService({database:e,schema:o,accountability:{admin:!0}}),a=await s.readAll("directus_settings"),c=a?.some(e=>e.field===C);if(c&&i)return;await s.createField("directus_settings",{field:C,type:"json",meta:{collection:"directus_settings",field:C,special:["cast-json"],interface:"input-code",hidden:!0,note:"Storage Manager extension settings (do not edit manually)"},schema:null}),Ne(),r.info(`[storage-manager] Created directus_settings.${C}`)}catch(e){r.warn(`[storage-manager] Could not ensure settings field: ${e?.message}`)}}function De(e,t){return`${e??""}::${t}`}function Be(e){const t=new Map;for(const n of e){const e=De(n.parent,n.name),r=t.get(e)??[];r.push(n.id),t.set(e,r)}for(const e of t.values())e.sort((e,t)=>e.localeCompare(t));return t}async function Ue(e){return(await e("directus_folders").select("id","name","parent")).map(e=>({id:String(e.id),name:String(e.name),parent:e.parent?String(e.parent):null}))}async function Re(e,t,n){const r=e("directus_folders").select("id").where("name",n);t?r.where("parent",t):r.whereNull("parent");return(await r).map(e=>String(e.id)).sort((e,t)=>e.localeCompare(t))}async function Me(e,t){const n=await Te(e);if(void 0!==n.name_mirror_claims)return n.name_mirror_claims;const r=function(e){const t={},n=Be(e);for(const[e,r]of n)r[0]&&(t[e]=r[0]);return t}(await Ue(e)),i={...n,name_mirror_claims:r};return await Ze(e,i),t?.info(`[storage-manager] Initialized name_mirror_claims (${Object.keys(r).length} sibling groups)`),r}async function qe(e,t){const n=await Te(e);await Ze(e,{...n,name_mirror_claims:t})}async function Le(e,t,n){const r=await t("directus_folders").select("id","name","parent").where("id",e).first();if(!r)return;const i=String(r.name),o=r.parent?String(r.parent):null,s=De(o,i),a={...await Me(t,n)};0!==(await Re(t,o,i)).filter(t=>t!==e).length?a[s]:a[s]!==e&&(a[s]=e,await qe(t,a))}async function We(e,t,n,r,i,o){if(t===n)return;const s={...await Me(i,o)},a=De(r,t),c=De(r,n);let l=!1;s[a]===e&&(delete s[a],l=!0);0===(await Re(i,r,n)).filter(t=>t!==e).length?s[c]!==e&&(s[c]=e,l=!0):s[c]===e||s[c],l&&await qe(i,s)}async function Je(e,t,n,r,i){const o={...await Me(r,i)},s=De(t,n);o[s]===e&&(delete o[s],await qe(r,o))}async function Ge(e,t){const n=await t("directus_folders").select("name","parent").where("id",e).first();return n?{name:String(n.name),parent:n.parent?String(n.parent):null}:null}function He(e){return"folder"===e}function Ve(e){return"folder_id"===e}function Ke(e){return He(t=e.prefix_strategy)||Ve(t);var t}function Xe(e,t,n,r){return(n.length?n:[t]).length<=1||r===t?e:`${e}_${t}`}async function Ye(e,t){if(!t)return null;return et(await Ue(e),t,"name",await Me(e))}async function Qe(e,t){if(!t)return null;return et(await Ue(e),t,"id")}function et(e,t,n,r={}){if(!t)return null;const i=new Map;for(const t of e)i.set(t.id,t);const o="name"===n?Be(e):null,s=[];let a=String(t),c=0;for(;a&&c<50;){const e=i.get(a);if(!e)break;if("id"===n)s.unshift(a);else{const t=De(e.parent,e.name),n=o.get(t)??[e.id];s.unshift(Xe(e.name,e.id,n,r[t]??null))}a=e.parent,c++}return s.length?s.join("/"):null}async function tt(e,t,n){switch(e.prefix_strategy){case"none":default:return null;case"folder":return await Ye(n,t.folder)||null;case"folder_id":return await Qe(n,t.folder)||null;case"type":{const n=(r=t.type)?r.split("/")[0]??"other":"other";return(e.type_map[n]??e.type_map.other??n)||null}case"date":{const n=e.date_format||"yyyy/MM";return function(e,t){const n=e?new Date(e):new Date;return t.replace("yyyy",String(n.getUTCFullYear())).replace("MM",String(n.getUTCMonth()+1).padStart(2,"0")).replace("dd",String(n.getUTCDate()).padStart(2,"0"))}(t.uploaded_on,n)}}var r}function nt(e){return String(e||"").replace(/\\/g,"/").replace(/\//g,"_").trim()}function rt(e,t){if(!e)return"";const n=[];let r=e,i=0;for(;r&&i<100;){const e=t.get(r);if(!e)break;n.unshift(nt(e.name)),r=e.parent,i+=1}return n.filter(Boolean).join("/")}async function it(e,t){if(!t)return[];const n=await e("directus_folders").select("id","parent"),r=new Map;for(const e of n){const t=null==e.parent?null:String(e.parent),n=String(e.id);r.has(t)||r.set(t,[]),r.get(t).push(n)}const i=[],o=[t];for(;o.length;){const e=o.pop();i.push(e);for(const t of r.get(e)||[])o.push(t)}return i}async function ot(e){const t=await e.database("directus_folders").select("id","name","parent"),r=new Map(t.map(e=>[String(e.id),{...e,id:String(e.id),parent:e.parent?String(e.parent):null}])),i=await it(e.database,e.folderId);let o=e.database("directus_files").select("id","storage","filename_disk","filesize","type","folder").whereNotNull("filename_disk");e.recursive?null!==e.folderId&&(o=o.whereIn("folder",[e.folderId,...i])):o=null===e.folderId?o.whereNull("folder"):o.whereIn("folder",i);const s=await o,a=[];let c=0,l=0,u=0,d=0;const f=Date.now();for(const e of s)d+=Number(e.filesize)||0;let p=0;e.onProgress?.({type:"start",mode:"move",from:"merge"===e.mode?null:"mixed",to:"merge"===e.mode?String(e.targetStorage||""):"preserve",total:s.length,total_bytes:d});for(let t=0;t<s.length;t++){const i=s[t];if(e.isCancelled?.())break;const o="merge"===e.mode?String(e.targetStorage||""):String(i.storage),g=rt(i.folder?String(i.folder):null,r),m=n.posix.basename(String(i.filename_disk||"")),h=g?`${g}/${m}`:m,_=String(i.filename_disk||i.id);if(e.onProgress?.({type:"file_start",index:t+1,total:s.length,id:String(i.id),name:_,filename_disk:String(i.filename_disk||""),from:String(i.storage),to:o,bytes:Number(i.filesize)||0}),e.structureOnly){const n={id:i.id,status:"skipped",filename_disk:h,from:String(i.storage),to:o,error:"Structure-only mode"};a.push(n),u+=1,e.onProgress?.({type:"file_done",index:t+1,total:s.length,result:n,name:_,succeeded:c,skipped:u,failed:l,transferred_bytes:p,total_bytes:d,elapsed_ms:Date.now()-f});continue}try{const n=await de(i,o,"move",e.database,e.logger,void 0,h,Boolean(e.keepSourceFileOnDisk));a.push(n),"failed"===n.status?l+=1:"skipped"===n.status?u+=1:(c+=1,p+=Number(n.bytes)||Number(i.filesize)||0),e.onProgress?.({type:"file_done",index:t+1,total:s.length,result:n,name:_,succeeded:c,skipped:u,failed:l,transferred_bytes:p,total_bytes:d,elapsed_ms:Date.now()-f})}catch(n){const r={id:i.id,status:"failed",filename_disk:h,from:String(i.storage),to:o,error:n?.message||"Materialize failed"};a.push(r),l+=1,e.onProgress?.({type:"file_done",index:t+1,total:s.length,result:r,name:_,succeeded:c,skipped:u,failed:l,transferred_bytes:p,total_bytes:d,elapsed_ms:Date.now()-f})}}const g={mode:"move",target_storage:"merge"===e.mode?String(e.targetStorage||""):"preserve",total:s.length,succeeded:c,failed:l,skipped:u,results:a,transferred_bytes:p,total_bytes:d,elapsed_ms:Date.now()-f};return e.onProgress?.({type:"done",data:g}),g}const st="directus-extension-storage-manager",at=`https://www.npmjs.com/package/${st}`;let ct=null;const lt=18e5;function ut(e){return String(e||"").trim().replace(/^v/,"")}function dt(e){const t=ut(e),[n,r]=t.split("-",2);return{nums:n.split(".").map(e=>parseInt(e,10)).map(e=>Number.isFinite(e)?e:0),prerelease:r?r.split("."):[]}}function ft(e=""){return`${e}/admin/settings/marketplace/extension/88a7639e-db2a-4ade-a97f-94d2cc3836e7`}async function pt(e=!1){if(!e&&ct&&Date.now()<ct.expiresAt)return ct.data;const t=ut(function(){const e=[];try{e.push(n.resolve(n.dirname(s(import.meta.url)),"..","package.json"))}catch{}e.push(n.resolve(process.cwd(),"extensions",st,"package.json"),n.resolve(process.cwd(),"package.json"));for(const t of e)try{const e=JSON.parse(i.readFileSync(t,"utf8"));if(e.name===st&&e.version)return String(e.version)}catch{}return"unknown"}()),r={npm:at,github:"https://github.com/domdus/directus-extension-storage-manager",marketplace:ft("")},o={current_version:t,latest_version:null,has_update:!1,registry:"npm",checked_at:(new Date).toISOString(),release_url:r.npm,links:r};try{const e=await fetch(`https://registry.npmjs.org/${encodeURIComponent(st)}`,{method:"GET",headers:{Accept:"application/json"}});if(!e.ok)throw new Error(`npm registry request failed (${e.status})`);const n=await e.json(),r=ut(n?.["dist-tags"]?.latest||"");if(!r)throw new Error("No latest version found in npm dist-tags");const i=function(e,t){const n=dt(e),r=dt(t),i=Math.max(n.nums.length,r.nums.length,3);for(let e=0;e<i;e++){const t=n.nums[e]??0,i=r.nums[e]??0;if(t>i)return 1;if(t<i)return-1}if(!n.prerelease.length&&r.prerelease.length)return 1;if(n.prerelease.length&&!r.prerelease.length)return-1;const o=Math.max(n.prerelease.length,r.prerelease.length);for(let e=0;e<o;e++){const t=n.prerelease[e],i=r.prerelease[e];if(null==t)return-1;if(null==i)return 1;const o=/^[0-9]+$/.test(t)?parseInt(t,10):null,s=/^[0-9]+$/.test(i)?parseInt(i,10):null;if(null==o||null==s){if(null!=o&&null==s)return-1;if(null==o&&null!=s)return 1;if(t>i)return 1;if(t<i)return-1}else{if(o>s)return 1;if(o<s)return-1}}return 0}(r,t)>0,s={...o,latest_version:r,has_update:i,release_url:i?`${at}?activeTab=versions`:at,checked_at:(new Date).toISOString()};return ct={data:s,expiresAt:Date.now()+lt},s}catch(e){const t={...o,error:e?.message||"Update check failed",checked_at:(new Date).toISOString()};return ct={data:t,expiresAt:Date.now()+Math.min(3e5,lt)},t}}async function*gt(e,t){const r=I(t,e),i=O(t,e);if("local"===r&&i)return void(yield*async function*(e){const t=n.isAbsolute(e)?e:n.join(process.cwd(),e);let r;try{r=await a.readdir(t,{withFileTypes:!0})}catch{return}for(const e of r)e.isFile()&&e.name&&!e.name.startsWith(".")&&"directus-health-file"!==e.name&&(yield e.name)}(i));const o=(await g()).location(e);try{for await(const e of v(o,"")){const t=String(e||"").replace(/^[/\\]+/,"");ve(t)&&(t.startsWith(".")||"directus-health-file"!==t&&(yield t))}}catch{}}async function mt(e,t){try{const n=(await g()).location(e),r=await y(n,t);return{filesize:Number(r.size)||0,type:ze(t)}}catch{return{filesize:0,type:ze(t)}}}async function ht(e){const t=function(e){const t=Number(e);return!Number.isFinite(t)||t<1?1:Math.floor(t)}(e.page),n=function(e,t=50){const n=Number(e);return!Number.isFinite(n)||n<1?t:Math.min(Math.floor(n),200)}(e.limit),r=e.search??null,i=(t-1)*n,o=[];let s=0,a=!1;for await(const t of gt(e.location,e.env))if(ke(t)&&Se(t,r)){if(!(s<i)){if(o.length<n){const n=await mt(e.location,t);o.push({filename_disk:t,filesize:n.filesize,type:n.type});continue}a=!0;break}s++}return{items:o,page:t,limit:n,has_more:a}}const _t=/[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/gi,yt=/(?:^|[^a-z0-9_])(?:\/?assets\/)([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})(?:\b|[/?#])/gi;function wt(e){return String(e||"").trim().toLowerCase()}function vt(e){if(!e)return[];const t=new Set;let n;for(yt.lastIndex=0;null!==(n=yt.exec(e));)n[1]&&t.add(wt(n[1]));return Array.from(t)}function kt(e){if(!e)return[];const t=new Set;let n;for(_t.lastIndex=0;null!==(n=_t.exec(e));)t.add(wt(n[0]));return Array.from(t)}function St(e){if(null==e)return"";if("string"==typeof e)return e;if("number"==typeof e||"boolean"==typeof e)return String(e);try{return JSON.stringify(e)}catch{return String(e)}}const bt=new Set(["directus_activity","directus_revisions","directus_sessions","directus_migrations","directus_notifications","directus_shares","directus_operations","directus_flows","directus_panels","directus_dashboards","directus_versions","directus_extensions","directus_permissions","directus_access","directus_policies","directus_presets","directus_deployments","directus_deployment_projects","directus_deployment_runs","unused_files","unused_files_iteration"]);function $t(e){return!e||(!!bt.has(e)||!!e.startsWith("directus_"))}const zt=new Set(["input-rich-text-html","input-rich-text-md","input-rich-text-mdm","input-code","input-multiline","input-block-editor","json","list","tags","markdown","wysiwyg"]),jt=new Set(["text","json","csv"]);function xt(e){return/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(e)}function At(e,t){const n=e?.collections?.[t]?.primary;return"string"==typeof n&&xt(n)?n:Array.isArray(n)&&1===n.length&&xt(String(n[0]))?String(n[0]):"id"}function Et(){return new Promise(e=>setImmediate(e))}function It(e){const t=Array.isArray(e?.relations)?e.relations:[],n=e?.collections&&"object"==typeof e.collections?e.collections:{},r=[],i=new Set;for(const e of t){if("directus_files"!==String(e?.related_collection||""))continue;const t=String(e.collection||""),o=String(e.field||"");if(!(t&&o&&xt(t)&&xt(o)))continue;if("directus_files"===t)continue;if(bt.has(t))continue;const s=`${t}.${o}`;if(i.has(s))continue;i.add(s);const a=n[t];r.push({collection:t,field:o,singleton:Boolean(a?.singleton)})}return r.sort((e,t)=>e.collection.localeCompare(t.collection)||e.field.localeCompare(t.field))}async function Ot(e,t){const n=await e("directus_fields").select("collection","field","interface","special"),r=t?.collections&&"object"==typeof t.collections?t.collections:{};return(n||[]).map(e=>{const t=String(e.collection||""),n=String(e.field||""),i=r[t]?.fields?.[n]?.type;return{collection:t,field:n,interface:null!=e.interface?String(e.interface):null,type:null!=i?String(i):null,special:null!=e.special?String(e.special):null}})}function Pt(e,t){const n=[],r=new Set;for(const i of e){const{collection:e,field:o}=i;if(!e||!o)continue;if(!xt(e)||!xt(o))continue;if($t(e))continue;if("directus_files"===e)continue;const s=`${e}.${o}`;if(t.has(s))continue;if(r.has(s))continue;const a=(i.special||"").toLowerCase();if(a.includes("alias")||a.includes("no-data"))continue;if(a.includes("file")||a.includes("files"))continue;const c=(i.interface||"").toLowerCase(),l=(i.type||"").toLowerCase(),u=zt.has(c),d=jt.has(l);(u||d)&&(r.add(s),n.push({collection:e,field:o,mode:(!d||"json"!==l&&"csv"!==l&&"input-code"!==c&&"json"!==c&&"list"!==c)&&u&&(c.includes("rich-text")||"wysiwyg"===c||"markdown"===c||"input-rich-text-md"===c||"input-block-editor"===c)?"assets_only":"assets_and_uuids"}))}return n.sort((e,t)=>e.collection.localeCompare(t.collection)||e.field.localeCompare(t.field))}async function Nt(e,t,n){if(n.has(t))return n.get(t);try{const r=Boolean(await e.schema.hasTable(t));return n.set(t,r),r}catch{return n.set(t,!1),!1}}async function Tt(e,t,n,r){const i=`${t}.${n}`;if(r.has(i))return r.get(i);try{const o=Boolean(await e.schema.hasColumn(t,n));return r.set(i,o),o}catch{return r.set(i,!1),!1}}function Zt(e,t){return t.storage&&e.where("storage",String(t.storage)),void 0!==t.folder&&null!==t.folder&&e.where("folder",String(t.folder)),t.cutoff&&e.andWhere(e=>{e.where("uploaded_on","<",t.cutoff).orWhereNull("uploaded_on")}),e}async function Ct(e,t,n={}){const r=Date.now(),i=Math.max(0,Number(n.minAgeMinutes??60)||0),o=!1!==n.scanTextFields,s=Math.min(500,Math.max(1,Number(n.limit??100)||100)),a=Math.max(0,Number(n.offset??0)||0),c=n.onProgress,l=n.isCancelled,u=It(t),d=new Set(u.map(e=>`${e.collection}.${e.field}`));let f=[];if(o){f=Pt(await Ot(e,t),d)}const p=await async function(e,t){const n=new Set,{relations:r,textTargets:i,scanTextFields:o,schema:s,logger:a,onProgress:c,isCancelled:l}=t,u=new Map,d=new Map;for(let t=0;t<r.length&&!l?.();t++){const i=r[t];c?.({phase:"relations",message:`Checking relation ${i.collection}.${i.field}`,current:t+1,total:r.length,used_count:n.size});try{if(!await Nt(e,i.collection,u))continue;if(!await Tt(e,i.collection,i.field,d))continue;if(i.singleton){const t=await e(i.collection).select(i.field).first(),r=t?.[i.field];if(null==r)continue;"object"==typeof r&&r.id?n.add(wt(r.id)):n.add(wt(String(r)));continue}const t=await e(i.collection).distinct(i.field).whereNotNull(i.field);for(const e of t){const t=e?.[i.field];null!=t&&n.add(wt(String(t)))}}catch(e){a?.warn(`[storage-manager] unreferenced: skip relation ${i.collection}.${i.field}: ${e?.message||e}`)}t%5==4&&await Et()}if(!o||!i.length||l?.())return n.delete(""),n;for(let t=0;t<i.length&&!l?.();t++){const r=i[t];c?.({phase:"text",message:`Scanning ${r.collection}.${r.field}`,current:t+1,total:i.length,used_count:n.size});try{if(!await Nt(e,r.collection,u))continue;if(!await Tt(e,r.collection,r.field,d))continue;const o=At(s,r.collection),a=await Tt(e,r.collection,o,d);let f=null,p=0,g=0;for(;!l?.();){let s=e(r.collection).whereNotNull(r.field).limit(500);a?(s=s.select(o,r.field).orderBy(o,"asc"),null!=f&&(s=s.where(o,">",f))):s=s.select(r.field).offset(p);const l=await s;if(!l.length)break;for(const e of l){const t=St(e?.[r.field]);if(t){for(const e of vt(t))n.add(e);if("assets_and_uuids"===r.mode)for(const e of kt(t))n.add(e)}}if(g+=l.length,a?f=l[l.length-1]?.[o]??f:p+=l.length,g%1e4==0&&(c?.({phase:"text",message:`Scanning ${r.collection}.${r.field} (${g.toLocaleString()} rows)`,current:t+1,total:i.length,used_count:n.size}),await Et()),l.length<500)break}}catch(e){a?.warn(`[storage-manager] unreferenced: skip text ${r.collection}.${r.field}: ${e?.message||e}`)}}return n.delete(""),n}(e,{relations:u,textTargets:f,scanTextFields:o,schema:t,logger:n.logger,onProgress:c,isCancelled:l});if(l?.())return{files:[],meta:{total_files:0,used_count:p.size,unreferenced_count:0,relation_targets:u.length,text_targets:f.length,collections_checked:new Set([...u.map(e=>e.collection),...f.map(e=>e.collection)]).size,min_age_minutes:i,scan_text_fields:o,elapsed_ms:Date.now()-r,truncated:!1,ids_truncated:!1,ids:[]}};const g=i>0?new Date(Date.now()-6e4*i).toISOString():null,m={storage:n.storage,folder:n.folder,cutoff:g},h=Zt(e("directus_files").count({total:"*"}),m),_=await h.first(),y=Number(_?.total??_?.["count(*)"]??0)||0;c?.({phase:"files",message:`Walking File Library (${y.toLocaleString()} files)`,current:0,total:y,used_count:p.size,unreferenced_count:0});const w=[];let v=0,k=!1,S=0,b=null;for(;!l?.();){const t=Zt(e("directus_files").select("id").orderBy("id","asc").limit(5e3),m);b&&t.where("id",">",b);const n=await t;if(!n.length)break;for(const e of n){const t=String(e.id);p.has(wt(t))||(v++,w.length<1e5?w.push(t):k=!0)}if(S+=n.length,b=String(n[n.length-1].id),c?.({phase:"files",message:`Checked ${S.toLocaleString()} / ${y.toLocaleString()} files`,current:S,total:y,used_count:p.size,unreferenced_count:v}),await Et(),n.length<5e3)break}c?.({phase:"finalize",message:"Preparing results",current:y,total:y,used_count:p.size,unreferenced_count:v});const $=w.slice(a,a+s);let z=[];if($.length){const t=await e("directus_files").select("id","title","filename_download","filename_disk","storage","type","filesize","folder","uploaded_on").whereIn("id",$),n=new Map(t.map(e=>[wt(e.id),e]));z=$.map(e=>n.get(wt(e))).filter(Boolean)}const j=new Set([...u.map(e=>e.collection),...f.map(e=>e.collection)]).size;return{files:z,meta:{total_files:y,used_count:p.size,unreferenced_count:v,relation_targets:u.length,text_targets:f.length,collections_checked:j,min_age_minutes:i,scan_text_fields:o,elapsed_ms:Date.now()-r,truncated:a+s<w.length||k,ids_truncated:k,ids:w}}}async function Ft(e,t,n,r={}){const i=wt(n);if(!i)return!1;const o=It(t),s=new Map,a=new Map;for(const t of o)try{if(!await Nt(e,t.collection,s))continue;if(!await Tt(e,t.collection,t.field,a))continue;if(await e(t.collection).select(t.field).where(t.field,i).first())return!0}catch(e){r.logger?.warn(`[storage-manager] refcheck relation ${t.collection}.${t.field}: ${e?.message||e}`)}if(!1===r.scanTextFields)return!1;const c=Pt(await Ot(e,t),new Set(o.map(e=>`${e.collection}.${e.field}`))),l=`%${i}%`;for(const t of c)try{if(!await Nt(e,t.collection,s))continue;if(!await Tt(e,t.collection,t.field,a))continue;const n=await e(t.collection).select(t.field).where(t.field,"like",l).first();if(!n)continue;const r=St(n[t.field]);if(("assets_only"===t.mode?vt(r):[...vt(r),...kt(r)]).includes(i))return!0}catch(e){r.logger?.warn(`[storage-manager] refcheck text ${t.collection}.${t.field}: ${e?.message||e}`)}return!1}async function Dt(e,t,n,r,i,o={}){const s=n.FilesService;if(!s)return i.map(e=>({id:e,status:"failed",reason:"FilesService unavailable"}));const a=new s({accountability:r,schema:t}),c=[];for(const n of i){const r=wt(n);if(r)try{if(!await e("directus_files").select("id").where("id",r).first()){c.push({id:r,status:"skipped",reason:"not found"});continue}if(await Ft(e,t,r,{scanTextFields:o.scanTextFields,logger:o.logger})){c.push({id:r,status:"skipped",reason:"still referenced"});continue}await a.deleteOne(r),c.push({id:r,status:"deleted"})}catch(e){c.push({id:r,status:"failed",reason:e?.message||String(e)})}else c.push({id:n,status:"skipped",reason:"invalid id"})}return c}function Bt(e,t){return!!l(e.accountability)||(t.status(403).json({errors:[{message:"Admin access required",extensions:{code:"FORBIDDEN"}}]}),!1)}async function Ut(e,t){const n=Oe((await Te(e)).lifecycle??Ie);return{minAgeMinutes:void 0!==t.min_age_minutes?Number(t.min_age_minutes):n.scan_min_age_minutes,scanTextFields:void 0!==t.scan_text_fields?Boolean(t.scan_text_fields):n.scan_text_fields,storage:t.storage??null,folder:void 0===t.folder?void 0:t.folder,limit:t.limit,offset:t.offset}}function Rt(e,t){return!!l(e.accountability)||(t.status(403).json({errors:[{message:"Admin access required",extensions:{code:"FORBIDDEN"}}]}),!1)}async function Mt(e,t,n){if(!t)return[];if(!n)return[t];const r=await e("directus_folders").select("id","parent"),i=new Map;for(const e of r){const t=null==e.parent?null:String(e.parent),n=String(e.id);i.has(t)||i.set(t,[]),i.get(t).push(n)}const o=[],s=[String(t)];for(;s.length;){const e=s.pop();o.push(e);const t=i.get(e)||[];for(const e of t)s.push(e)}return o}function qt(e,t){const n=t.map(e=>B(e)).filter(Boolean);n.length&&e.where(function(){for(const e of n)this.orWhere("filename_disk",e).orWhere("filename_disk","like",`${e}/%`)})}async function Lt(e,t,n){const r=Array.isArray(n.file_ids)?n.file_ids.map(String).filter(Boolean):[],i=Array.isArray(n.source_folders)?n.source_folders.map(String):[];r.length&&i.length?e.where(function(){this.whereIn("id",r).orWhere(function(){qt(this,i)})}):r.length?e.whereIn("id",r):i.length&&qt(e,i),n.source_storage&&e.where("storage",String(n.source_storage));const o=null!=n.source_path?B(String(n.source_path)):"";if(o){if(!n.source_storage)return void e.whereRaw("1 = 0");const t=`${o}/`;!1===n.recursive?e.where("filename_disk","like",`${t}%`).whereNot("filename_disk","like",`${t}%/%`):e.where("filename_disk","like",`${t}%`)}if(void 0!==n.folder_id)if(null===n.folder_id||""===n.folder_id)e.whereNull("folder");else{const r=await Mt(t,String(n.folder_id),Boolean(n.recursive));0===r.length?e.where("folder",String(n.folder_id)):e.whereIn("folder",r)}}async function Wt(e,t){if(Array.isArray(t.file_ids)&&t.file_ids.length>0)return t.file_ids.map(String);const n=e("directus_files").select("id");await Lt(n,e,{...t,file_ids:void 0});return(await n).map(e=>String(e.id))}function Jt(e){return String(e?.client?.config?.client||e?.client?.dialect||"").toLowerCase()}async function Gt(e,t,n,r,i,o){if(o.length&&!i)return null;const s=B(r);let a;const c=[];if(i)s?(a=Jt(e).includes("sqlite")?"? || '/' || src.filename_disk":"CONCAT(?, '/', src.filename_disk)",c.push(s)):a="src.filename_disk";else{const t=function(e,t){const n=Jt(e);return n.includes("pg")||n.includes("cockroach")?`regexp_replace(${t}, '^.*/', '')`:n.includes("mysql")?`SUBSTRING_INDEX(${t}, '/', -1)`:n.includes("mssql")?`CASE WHEN CHARINDEX('/', ${t}) = 0 THEN ${t} ELSE RIGHT(${t}, CHARINDEX('/', REVERSE(${t})) - 1) END`:""}(e,"src.filename_disk");if(!t)return null;s?(a=Jt(e).includes("sqlite")?`? || '/' || (${t})`:`CONCAT(?, '/', ${t})`,c.push(s)):a=t}try{const r=t.clone().clearSelect().select("id","filename_disk").as("src"),i=await e.from(r).joinRaw(`inner join directus_files as occ on occ.storage = ? and occ.id <> src.id and occ.filename_disk = ${a}`,[n,...c]).count("* as n").first();return Number(i?.n??0)}catch{return null}}function Ht(e,t){if(!e)return 0;for(const n of t)if(null!=e[n]&&""!==e[n])return Number(e[n])||0;return 0}var Vt={id:"storage-manager",handler:(e,t)=>{const{database:r,env:i,logger:o,services:s,getSchema:u}=t;e.use(async(e,t,n)=>{try{await Fe(r,s,u,o),n()}catch(e){n(e)}}),function(e,t){const{database:n,logger:r,services:i,getSchema:o}=t;e.post("/unreferenced/scan",async(e,t,i)=>{try{if(!Bt(e,t))return;const i=e.body||{},s=await Ut(n,i),a=await o(),c=await Ct(n,a,{...s,logger:r});r.info(`[storage-manager] unreferenced scan: files=${c.meta.total_files} used≈${c.meta.used_count} unreferenced=${c.meta.unreferenced_count} relations=${c.meta.relation_targets} text=${c.meta.text_targets} ${c.meta.elapsed_ms}ms`),t.json({data:c.files,meta:c.meta})}catch(e){i(e)}}),e.post("/unreferenced/scan/stream",async(e,t,i)=>{try{if(!Bt(e,t))return;const i=e.body||{},s=await Ut(n,i),a=await o();t.status(200),t.setHeader("Content-Type","text/event-stream; charset=utf-8"),t.setHeader("Cache-Control","no-cache, no-transform"),t.setHeader("Connection","keep-alive"),t.setHeader("X-Accel-Buffering","no"),t.flushHeaders?.();let c=!1;const l=()=>{c=!0};e.on("close",l),t.on("close",l);const u=e=>{if(c)return;t.write(`data: ${JSON.stringify(e)}\n\n`);const n=t.flush;"function"==typeof n&&n.call(t)},d=setInterval(()=>{u({type:"heartbeat",ts:Date.now()})},12e3);try{u({type:"start",message:"Starting unreferenced scan"});const e=await Ct(n,a,{...s,logger:r,isCancelled:()=>c,onProgress:e=>{u({type:"progress",...e})}});if(c)return;r.info(`[storage-manager] unreferenced scan (stream): files=${e.meta.total_files} used≈${e.meta.used_count} unreferenced=${e.meta.unreferenced_count} ${e.meta.elapsed_ms}ms`),u({type:"done",data:e.files,meta:e.meta})}catch(e){u({type:"error",message:e instanceof Error?e.message:String(e)})}finally{clearInterval(d),c||t.end()}}catch(e){if(!t.headersSent)return void i(e);try{t.write(`data: ${JSON.stringify({type:"error",message:e instanceof Error?e.message:String(e)})}\n\n`),t.end()}catch{}}}),e.post("/unreferenced/delete",async(e,t,s)=>{try{if(!Bt(e,t))return;const s=Oe((await Te(n)).lifecycle??Ie),a=e.body||{},c=Array.isArray(a.file_ids)?a.file_ids.map(String).filter(Boolean):[];if(!c.length)return void t.status(400).json({errors:[{message:"Provide file_ids — at least one file to delete"}]});if(c.length>500)return void t.status(400).json({errors:[{message:"Delete at most 500 files per request"}]});const l=await o(),u=await Dt(n,l,i,e.accountability,c,{scanTextFields:void 0!==a.scan_text_fields?Boolean(a.scan_text_fields):s.scan_text_fields,logger:r});r.info(`[storage-manager] unreferenced delete: total=${u.length} deleted=${u.filter(e=>"deleted"===e.status).length}`),t.json({data:{total:u.length,deleted:u.filter(e=>"deleted"===e.status).length,skipped:u.filter(e=>"skipped"===e.status).length,failed:u.filter(e=>"failed"===e.status).length,results:u}})}catch(e){s(e)}}),e.post("/files/delete-if-unreferenced",async(e,t,s)=>{try{if(!e.accountability?.user&&!l(e.accountability))return void t.status(403).json({errors:[{message:"Authentication required",extensions:{code:"FORBIDDEN"}}]});const s=Oe((await Te(n)).lifecycle??Ie),a=e.body||{},c=(Array.isArray(a.file_ids)?a.file_ids:Array.isArray(a.ids)?a.ids:[]).map(String).filter(Boolean);if(!c.length)return void t.status(400).json({errors:[{message:"Provide file_ids"}]});if(c.length>50)return void t.status(400).json({errors:[{message:"At most 50 file ids per request"}]});const u=await o(),d=await Dt(n,u,i,e.accountability,c,{scanTextFields:s.scan_text_fields,logger:r});t.json({data:{total:d.length,deleted:d.filter(e=>"deleted"===e.status).length,skipped:d.filter(e=>"skipped"===e.status).length,failed:d.filter(e=>"failed"===e.status).length,results:d}})}catch(e){s(e)}})}(e,t),e.get("/storages",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=E(i),o=await Te(r),s=await N(r,n),a=await Promise.all(n.map(async e=>{const t=await Z(i,r,e,s.get(e));return t.mirror_directus_folders=Ke(Ce(o,e)),t}));t.json({data:a})}catch(e){n(e)}}),e.get("/update-check",async(e,t,n)=>{try{if(!Rt(e,t))return;const n="1"===String(e.query.force||""),r=await pt(n);t.json({data:r})}catch(e){n(e)}}),e.get("/storages/:location",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const o=await Z(i,r,n),s=await Te(r);o.mirror_directus_folders=Ke(Ce(s,n)),t.json({data:o})}catch(e){n(e)}}),e.get("/storages/:location/root-transforms",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const r="string"==typeof e.query.search?e.query.search:null,o=await ht({location:n,env:i,page:e.query.page,limit:e.query.limit,search:r});t.json({data:o.items,meta:{page:o.page,limit:o.limit,has_more:o.has_more}})}catch(e){n(e)}}),e.get("/storages/:location/root-transforms/count",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const r="string"==typeof e.query.search?e.query.search:null,o=null!=e.query.max?Number(e.query.max):void 0,s=await async function(e){const t=Math.min(Math.max(Number(e.max)||1e5,1),1e6);let n=0;for await(const r of gt(e.location,e.env))if(ke(r)&&Se(r,e.search??null)&&(n++,n>=t))return{count:t,capped:!0};return{count:n,capped:!1}}({location:n,env:i,search:r,max:o});t.json({data:s})}catch(e){n(e)}}),e.post("/storages/:location/root-transforms/delete-all",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const s=e.body||{},a=await async function(e){const t=(await g()).location(e.location),n=e.search??null,r=Boolean(e.dryRun);let i=0,o=0,s=0,a=0;const c=[];for await(const l of gt(e.location,e.env))if(ke(l)&&Se(l,n)){a++;try{if(await e.database("directus_files").select("id").where({storage:e.location,filename_disk:l}).first()){o++;continue}if(r){i++;continue}if(!await _(t,l)){o++;continue}await w(t,l),i++}catch(t){s++;const n=t?.message||String(t);c.push({filename_disk:l,error:n}),e.logger?.warn(`[storage-manager] Transform delete failed for ${l}: ${n}`)}}return!r&&i>0&&e.logger?.info(`[storage-manager] Deleted ${i} root transform(s) on ${e.location} (skipped ${o}, failed ${s})`),{dry_run:r,deleted:i,skipped:o,failed:s,scanned:a,errors:c.slice(0,20)}}({database:r,location:n,env:i,search:s.search??null,dryRun:Boolean(s.dry_run),logger:o});t.json({data:a})}catch(e){n(e)}}),e.get("/storages/:location/browse",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const o=B(String(e.query.path||"")),s=await H(r,n,o,i);t.json({data:s})}catch(e){n(e)}}),e.get("/storages/:location/folder-tree",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const o=await async function(e,t,n){const{folders:r}=await H(e,t,"",n);return r.map(e=>({name:e.name,path:e.path}))}(r,n,i);t.json({data:o})}catch(e){n(e)}}),e.post("/storages/:location/folders",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const r=e.body||{},o=await te(n,String(r.name||""),String(r.parent_path||""),i);t.json({data:o})}catch(e){if(e?.message&&/required|Invalid|cannot contain/i.test(e.message))return void t.status(400).json({errors:[{message:e.message}]});n(e)}}),e.delete("/storages/:location/folders",async(e,n,s)=>{try{if(!Rt(e,n))return;const s=String(e.params.location);if(!E(i).includes(s))return void n.status(404).json({errors:[{message:`Unknown storage location: ${s}`}]});const c=e.body||{},l=Array.isArray(c.paths)?c.paths.map(String):[];if(!l.length)return void n.status(400).json({errors:[{message:"Provide paths — at least one storage folder to delete"}]});const u="delete"===c.mode?"delete":"move";let d;try{const n=await t.getSchema(),r=t.services.FilesService;r&&(d=new r({accountability:e.accountability,schema:n}))}catch{d=void 0}const f=await async function(e,t,n,r,i,o){const s="delete"===o?.mode?"delete":"move",c=[],l=[];let u=0,d=0;const f=I(r,t),p=(await g()).location(t);for(const g of n){const n=B(g);if(!n){l.push({path:String(g),error:"Invalid path"});continue}const m=re(n);try{let g=0;if("delete"===s){const r=(await e("directus_files").select("id","filename_disk").where("storage",t).whereRaw("filename_disk LIKE ?",[`${n}/%`])).filter(e=>!M(String(e.filename_disk||""))),i=r.map(e=>String(e.id));if(i.length){if(o?.filesService)await o.filesService.deleteMany(i);else for(const t of r){const n=String(t.id),r=String(t.filename_disk||"");try{r&&await j(p,r)}catch{}await e("directus_files").where("id",n).delete()}g=i.length,d+=i.length}}else{const{moved:r,failed:o}=await se(e,t,n,m,i);if(u+=r,o>0){l.push({path:n,error:`Could not move ${o} registered file(s) to parent`});continue}}if("local"===f){const e=O(r,t);if(!e)throw new Error("Missing local root");const i=q(e,n);await a.rm(i,{recursive:!0,force:!0})}else try{for await(const e of v(p,`${n}/`)){const t=String(e||"").replace(/^[/\\]+/,"");if(t.startsWith(`${n}/`)&&M(t))try{await w(p,t)}catch{}}}catch{const e=`${n}/${F}`;await _(p,e)&&await w(p,e)}c.push(n),i?.info("delete"===s?`[storage-manager] Deleted storage folder “${n}” on ${t} (deleted ${g} registered file(s))`:`[storage-manager] Deleted storage folder “${n}” on ${t} (relocated files to parent)`)}catch(e){l.push({path:n,error:e?.message||String(e)})}}return{deleted:c,skipped:l,relocated:u,files_deleted:d}}(r,s,l,i,o,{mode:u,filesService:d});n.json({data:f})}catch(e){s(e)}}),e.patch("/storages/:location/folders",async(e,t,s)=>{try{if(!Rt(e,t))return;const s=String(e.params.location);if(!E(i).includes(s))return void t.status(404).json({errors:[{message:`Unknown storage location: ${s}`}]});const a=e.body||{},c=String(a.path||"");if(!c)return void t.status(400).json({errors:[{message:"Provide path — the storage folder to update"}]});const l=void 0!==a.name&&null!==a.name,u=Object.prototype.hasOwnProperty.call(a,"parent_path");if(!l&&!u)return void t.status(400).json({errors:[{message:"Provide name (rename) and/or parent_path (move)"}]});let d;if(l&&u){const e=String(a.name||"").trim(),t=U(String(a.parent_path??""),e);d=await oe(r,s,c,t,i,o)}else d=l?await async function(e,t,n,r,i,o){const s=B(n);if(!s)throw new Error("Folder path is required");const a=L(r);return oe(e,t,s,U(re(s),a),i,o)}(r,s,c,String(a.name||""),i,o):await async function(e,t,r,i,o,s){const a=B(r);if(!a)throw new Error("Folder path is required");return oe(e,t,a,U(B(i),n.posix.basename(a)),o,s)}(r,s,c,String(a.parent_path??""),i,o);t.json({data:d})}catch(e){if(e?.message&&/required|Invalid|cannot|already exists|Failed to relocate/i.test(e.message))return void t.status(400).json({errors:[{message:e.message}]});s(e)}}),e.post("/storages/:location/move-files",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const s=e.body||{},a=Array.isArray(s.file_ids)?s.file_ids.map(String):[],c=Array.isArray(s.source_folders)?s.source_folders.map(String):[];if(!a.length&&!c.length&&!s.source_storage)return void t.status(400).json({errors:[{message:"Provide file_ids or source_folders"}]});const l=a.length?await ne(r,n,a,String(s.target_path??""),o,i,c,Boolean(s.preserve_paths)):{moved:0,failed:0,skipped:0,results:[]};!1!==s.include_empty_folders&&(c.length||s.source_storage)&&await ee({database:r,sourceLocation:String(s.source_storage||n),targetLocation:n,env:i,targetPath:String(s.target_path??""),sourceFolders:c.length?c:void 0,removeSource:!0,logger:o}),t.json({data:l})}catch(e){n(e)}}),e.post("/storages/:location/place-file",async(e,t,o)=>{try{if(!Rt(e,t))return;const o=String(e.params.location);if(!E(i).includes(o))return void t.status(404).json({errors:[{message:`Unknown storage location: ${o}`}]});const s=e.body||{};if(!s.file_id)return void t.status(400).json({errors:[{message:"Provide file_id"}]});const a=await async function(e,t,r,i){const o=B(i);if(!o)return null;const s=await e("directus_files").select("id","storage","filename_disk","type").where("id",t).first();if(!s||String(s.storage)!==r)return null;const a=String(s.filename_disk||""),c=n.posix.basename(a);if(!a||a===`${o}/${c}`)return a;const l=(await ne(e,r,[t],o)).results[0];if("moved"===l?.status)return l.to;throw new Error(l?.error||"Failed to place file under storage path")}(r,String(s.file_id),o,String(s.target_path||""));t.json({data:{id:s.file_id,filename_disk:a}})}catch(e){t.status(400).json({errors:[{message:e?.message||"Place file failed"}]})}}),e.get("/storages/:location/orphans",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const o="string"==typeof e.query.path?e.query.path:"",s=await Ee(r,n,i,o);t.json({data:s.orphans,meta:{scanned:s.scanned,known:s.known,orphan_count:s.orphans.length,path:s.path||null}})}catch(e){n(e)}}),e.post("/storages/:location/import-orphans",async(e,t,s)=>{try{if(!Rt(e,t))return;const s=String(e.params.location);if(!E(i).includes(s))return void t.status(404).json({errors:[{message:`Unknown storage location: ${s}`}]});const a=e.body||{};let l=Array.isArray(a.filename_disks)?a.filename_disks.map(String):[];if(0===l.length){l=(await Ee(r,s,i,a.path||"")).orphans.map(e=>e.filename_disk)}if(0===l.length)return void t.json({data:{total:0,imported:0,skipped:0,failed:0,results:[]}});const u=await async function(e,t,r,i){const o=(await g()).location(t),s=[];for(const a of r){const r=String(a||"").trim();if(r&&!be(r))try{const a=await e("directus_files").select("id").where({storage:t,filename_disk:r}).first();if(a){s.push({filename_disk:r,id:String(a.id),status:"skipped",error:"Already in database"});continue}if(!await _(o,r)){s.push({filename_disk:r,status:"failed",error:"File not found on disk"});continue}const l=await y(o,r),u=xe(r);let d=u||c();u&&await e("directus_files").select("id").where({id:u}).first()&&(d=c());const f=new Date,p=n.basename(r),g=ze(r),m=je(r);let h=null,w=null;if(me(g)){const e=await _e(o,r);e&&(h=e.width,w=e.height)}await e("directus_files").insert({id:d,storage:t,filename_disk:r,filename_download:p,title:m,type:g,filesize:Number(l.size)||0,width:h,height:w,folder:i?.folder||null,uploaded_on:f,modified_on:f}),s.push({filename_disk:r,id:d,status:"imported"})}catch(e){s.push({filename_disk:r,status:"failed",error:e?.message||String(e)})}else s.push({filename_disk:r,status:"skipped",error:"Ignored path"})}return s}(r,s,l,{folder:void 0===a.folder?null:a.folder});o.info(`[storage-manager] import-orphans location=${s} total=${u.length} imported=${u.filter(e=>"imported"===e.status).length}`),t.json({data:{total:u.length,imported:u.filter(e=>"imported"===e.status).length,skipped:u.filter(e=>"skipped"===e.status).length,failed:u.filter(e=>"failed"===e.status).length,results:u}})}catch(e){s(e)}}),e.post("/storages/:location/delete-orphans",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const s=e.body||{},a=Array.isArray(s.filename_disks)?s.filename_disks.map(String).filter(Boolean):[];if(0===a.length)return void t.status(400).json({errors:[{message:"Provide filename_disks — at least one orphan to delete"}]});const c=await async function(e,t,n){const r=(await g()).location(t),i=[];for(const o of n){const n=String(o||"").trim();if(n&&!be(n))try{if(await e("directus_files").select("id").where({storage:t,filename_disk:n}).first()){i.push({filename_disk:n,status:"skipped",error:"Registered in Directus — use File Library to delete"});continue}if(!await _(r,n)){i.push({filename_disk:n,status:"skipped",error:"Not found on disk"});continue}await w(r,n),i.push({filename_disk:n,status:"deleted"})}catch(e){i.push({filename_disk:n,status:"failed",error:e?.message||String(e)})}else i.push({filename_disk:n,status:"skipped",error:n&&we(n)?"Generated thumbnail":"Ignored path"})}return i}(r,n,a);o.info(`[storage-manager] delete-orphans location=${n} total=${c.length} deleted=${c.filter(e=>"deleted"===e.status).length}`),t.json({data:{total:c.length,deleted:c.filter(e=>"deleted"===e.status).length,skipped:c.filter(e=>"skipped"===e.status).length,failed:c.filter(e=>"failed"===e.status).length,results:c}})}catch(e){n(e)}}),e.get("/files",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=e.query.storage?String(e.query.storage):null,i=void 0!==e.query.folder?"null"===e.query.folder||""===e.query.folder?null:String(e.query.folder):void 0,o=e.query.search?String(e.query.search).trim():"",s=function(e){if(!e)return null;try{const t="string"==typeof e?JSON.parse(e):e;if(t&&"object"==typeof t&&!Array.isArray(t))return t}catch{}return null}(e.query.filter),a="true"===String(e.query.recursive||""),c=Math.max(1,parseInt(String(e.query.page||"1"),10)||1),l=Math.min(200,Math.max(1,parseInt(String(e.query.limit||"50"),10)||50)),u=String(e.query.sort||"-uploaded_on"),d=r("directus_files").select("id","title","filename_download","filename_disk","storage","type","filesize","folder","uploaded_on","modified_on");if(n&&d.where("storage",n),void 0!==i)if(null===i)d.whereNull("folder");else if(a){const e=await Mt(r,i,!0);d.whereIn("folder",e)}else d.where("folder",i);if(o){const e=`%${o.replace(/[%_]/g,"\\$&")}%`;d.andWhere(t=>{t.where("title","like",e).orWhere("filename_download","like",e).orWhere("filename_disk","like",e)})}!function(e,t){if(!t)return;const n=(e,t)=>{if(t._and&&Array.isArray(t._and))for(const r of t._and)r&&"object"==typeof r&&n(e,r);else if(t._or&&Array.isArray(t._or))e.andWhere(e=>{for(const r of t._or)r&&"object"==typeof r&&e.orWhere(e=>n(e,r))});else for(const[n,r]of Object.entries(t)){if(n.startsWith("_"))continue;if(!r||"object"!=typeof r)continue;const t=r;"_eq"in t&&e.andWhere(n,t._eq),"_neq"in t&&e.andWhereNot(n,t._neq),"_null"in t&&e.whereNull(n),"_nnull"in t&&e.whereNotNull(n),"_contains"in t&&e.andWhere(n,"like",`%${String(t._contains)}%`),"_in"in t&&Array.isArray(t._in)&&e.whereIn(n,t._in)}};n(e,t)}(d,s);const f=d.clone().clearSelect().count({count:"*"}).first(),p=d.clone().clearSelect().sum({total_bytes:"filesize"}).first(),g=u.startsWith("-")?u.slice(1):u,m=u.startsWith("-")?"desc":"asc",h=new Set(["uploaded_on","modified_on","filename_download","filesize","title","storage","type"]).has(g)?g:"uploaded_on",_=await d.clone().orderBy(h,m).limit(l).offset((c-1)*l),y=await f,w=await p,v=Number(y?.count||0),k=Number(w?.total_bytes||0);t.json({data:_,meta:{total_count:v,filter_count:v,total_bytes:k,page:c,limit:l}})}catch(e){n(e)}}),e.get("/folders",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=void 0===e.query.parent?void 0:"null"===e.query.parent||""===e.query.parent?null:String(e.query.parent),i=e.query.storage?String(e.query.storage):null;let o=r("directus_folders").select("id","name","parent").orderBy("name","asc");null===n?o=o.whereNull("parent"):void 0!==n&&(o=o.where("parent",n));const s=await o,a=[];for(const e of s){const t=String(e.id);let n=r("directus_files").where("folder",t);i&&(n=n.andWhere("storage",i));const o=await n.select(r.raw("count(*) as file_count"),r.raw("coalesce(sum(filesize), 0) as total_bytes")).first(),s=await r("directus_folders").where("parent",t).count({count:"*"}).first();a.push({id:t,name:e.name,parent:null==e.parent?null:String(e.parent),file_count:Number(o?.file_count||0),total_bytes:Number(o?.total_bytes||0),child_count:Number(s?.count||0)})}let c=null;if(null==n){let e=r("directus_files").whereNull("folder");i&&(e=e.andWhere("storage",i));const t=await e.select(r.raw("count(*) as file_count"),r.raw("coalesce(sum(filesize), 0) as total_bytes")).first();c={file_count:Number(t?.file_count||0),total_bytes:Number(t?.total_bytes||0)}}t.json({data:a,meta:{root_files:c}})}catch(e){n(e)}}),e.get("/folders/tree",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=(await r("directus_folders").select("id","name","parent").orderBy("name","asc")).map(e=>({id:String(e.id),name:e.name,parent:null==e.parent?null:String(e.parent)}));t.json({data:n})}catch(e){n(e)}}),e.get("/folders/:id/path",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.id),i=[];let o=n;for(let e=0;e<50&&o;e++){const e=await r("directus_folders").select("id","name","parent").where({id:o}).first();if(!e)break;i.unshift({id:String(e.id),name:e.name}),o=null==e.parent?null:String(e.parent)}t.json({data:i})}catch(e){n(e)}}),e.post("/migrate/dry-run",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=e.body||{},o=String(n.target_storage||"").trim(),s=E(i);if(!o||!s.includes(o))return void t.status(400).json({errors:[{message:"Provide a valid target_storage"}]});const a=Array.isArray(n.file_ids)?n.file_ids.map(String).filter(Boolean):[],c=Array.isArray(n.source_folders)?n.source_folders.map(String):[];if(!(a.length>0||Boolean(n.source_storage)||void 0!==n.folder_id||c.length>0))return void t.status(400).json({errors:[{message:"Provide file_ids, source_storage, or folder_id"}]});const l=null!=n.target_path?String(n.target_path):"",u=Boolean(n.preserve_paths),d=r("directus_files");await Lt(d,r,n);const f=await d.clone().clearSelect().count("* as n").sum("filesize as bytes").first(),p=Ht(f,["n","count"]),g=Ht(f,["bytes","sum"]),m=(await d.clone().clearSelect().select("id","storage","filename_disk").limit(20)).map(e=>{const t=String(e.filename_disk||""),n=R(t,l,c,u);return{id:String(e.id),storage:String(e.storage),from:t,to:n}}),h=[...new Set(m.map(e=>e.to).filter(Boolean))],_=h.length?await r("directus_files").select("id","filename_disk").where({storage:o}).whereIn("filename_disk",h):[],y=new Map;for(const e of _)y.set(String(e.filename_disk),String(e.id));const w=[];for(const e of m){const t=y.get(e.to);w.push({from:`${e.storage}:${e.from}`,to:`${o}:${e.to}`,skipped:Boolean(t&&t!==e.id)})}const v=await Gt(r,d,o,l,u,c);t.json({data:{total_files:p,total_folders:0,empty_folders:0,total_bytes:g,skipped:v,samples:w}})}catch(e){n(e)}}),e.post("/migrate",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=e.body||{},s=String(n.target_storage||"").trim(),a="copy"===n.mode?"copy":"move"===n.mode?"move":null;if(!s||!a)return void t.status(400).json({errors:[{message:'target_storage and mode ("copy"|"move") are required'}]});const c=E(i);if(!c.includes(s))return void t.status(400).json({errors:[{message:`Unknown target storage: ${s}. Available: ${c.join(", ")}`}]});if(I(i,s),n.source_storage&&!c.includes(String(n.source_storage)))return void t.status(400).json({errors:[{message:`Unknown source storage: ${n.source_storage}`}]});if(!(Array.isArray(n.file_ids)&&n.file_ids.length>0||Boolean(n.source_storage)||void 0!==n.folder_id))return void t.status(400).json({errors:[{message:"Provide file_ids, source_storage, and/or folder_id to select files to migrate"}]});const l=await Wt(r,n);if(0===l.length)return void t.json({data:{mode:a,target_storage:s,total:0,succeeded:0,skipped:0,failed:0,results:[]}});const u=5e3;if(l.length>u)return void t.status(400).json({errors:[{message:`Selection contains ${l.length} files (max ${u} per request). Narrow the selection or run in batches.`}]});o.info(`[storage-manager] Starting ${a} of ${l.length} file(s) → ${s} (by ${e.accountability?.user||"unknown"})`);const d=await fe({fileIds:l,targetStorage:s,mode:a,keepSourceFileOnDisk:Boolean(n.keep_source_file_on_disk),targetPath:null!=n.target_path?String(n.target_path):void 0,sourceFolders:Array.isArray(n.source_folders)?n.source_folders.map(String):void 0,includeEmptyFolders:!1!==n.include_empty_folders,preservePaths:Boolean(n.preserve_paths),sourceStorage:n.source_storage?String(n.source_storage):void 0,sourcePath:null!=n.source_path?String(n.source_path):void 0,concurrency:n.concurrency,database:r,logger:o,env:i});t.json({data:d})}catch(e){n(e)}}),e.post("/migrate/stream",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=e.body||{},s=String(n.target_storage||"").trim(),a="copy"===n.mode?"copy":"move"===n.mode?"move":null;if(!s||!a)return void t.status(400).json({errors:[{message:'target_storage and mode ("copy"|"move") are required'}]});const c=E(i);if(!c.includes(s))return void t.status(400).json({errors:[{message:`Unknown target storage: ${s}. Available: ${c.join(", ")}`}]});if(I(i,s),n.source_storage&&!c.includes(String(n.source_storage)))return void t.status(400).json({errors:[{message:`Unknown source storage: ${n.source_storage}`}]});if(!(Array.isArray(n.file_ids)&&n.file_ids.length>0||Boolean(n.source_storage)||void 0!==n.folder_id))return void t.status(400).json({errors:[{message:"Provide file_ids, source_storage, and/or folder_id to select files to migrate"}]});const l=await Wt(r,n),u=5e3;if(l.length>u)return void t.status(400).json({errors:[{message:`Selection contains ${l.length} files (max ${u} per request). Narrow the selection or run in batches.`}]});t.status(200),t.setHeader("Content-Type","text/event-stream; charset=utf-8"),t.setHeader("Cache-Control","no-cache, no-transform"),t.setHeader("Connection","keep-alive"),t.setHeader("X-Accel-Buffering","no"),t.flushHeaders?.();let d=!1;const f=()=>{d=!0};e.on("close",f),t.on("close",f);const p=e=>{if(d)return;t.write(`data: ${JSON.stringify(e)}\n\n`);const n=t.flush;"function"==typeof n&&n.call(t)};o.info(`[storage-manager] Streaming ${a} of ${l.length} file(s) → ${s} (by ${e.accountability?.user||"unknown"})`);try{await fe({fileIds:l,targetStorage:s,mode:a,keepSourceFileOnDisk:Boolean(n.keep_source_file_on_disk),targetPath:null!=n.target_path?String(n.target_path):void 0,sourceFolders:Array.isArray(n.source_folders)?n.source_folders.map(String):void 0,includeEmptyFolders:!1!==n.include_empty_folders,preservePaths:Boolean(n.preserve_paths),sourceStorage:n.source_storage?String(n.source_storage):void 0,sourcePath:null!=n.source_path?String(n.source_path):void 0,concurrency:n.concurrency??1,database:r,logger:o,env:i,isCancelled:()=>d,onProgress:e=>p(e)})}catch(e){p({type:"error",message:e instanceof Error?e.message:String(e)})}d||t.end()}catch(e){if(!t.headersSent)return void n(e);try{t.write(`data: ${JSON.stringify({type:"error",message:e instanceof Error?e.message:String(e)})}\n\n`),t.end()}catch{}}}),e.post("/materialize/dry-run",async(e,t,o)=>{try{if(!Rt(e,t))return;const o=e.body||{},s="merge"===o.mode?"merge":"preserve",a=void 0===o.folder_id||null===o.folder_id||""===o.folder_id?null:String(o.folder_id),c=String(o.target_storage||"").trim();if("merge"===s&&!c)return void t.status(400).json({errors:[{message:'target_storage is required when mode is "merge"'}]});if("merge"===s){if(!E(i).includes(c))return void t.status(400).json({errors:[{message:`Unknown target storage: ${c}`}]})}const l=await async function(e){const t=await e.database("directus_folders").select("id","name","parent"),r=new Map(t.map(e=>[String(e.id),{...e,id:String(e.id),parent:e.parent?String(e.parent):null}])),i=await it(e.database,e.folderId);let o=e.database("directus_files").select("id","storage","filename_disk","filesize","folder").whereNotNull("filename_disk");e.recursive?null!==e.folderId&&(o=o.whereIn("folder",[e.folderId,...i])):o=null===e.folderId?o.whereNull("folder"):o.whereIn("folder",i);const s=await o,a=await g(),c=new Set;let l=0;const u=new Map,d=[];for(const t of s){const i="merge"===e.mode?String(e.targetStorage||""):String(t.storage),o=rt(t.folder?String(t.folder):null,r),s=n.posix.basename(String(t.filename_disk||"")),f=o?`${o}/${s}`:s,p=`${i}::${f}`;c.has(p)&&(l+=1),c.add(p);const g=String(t.filename_disk||"").replace(/\\/g,"/").replace(/^\/+/,"");if(t.storage!==i||g!==f)try{const e=a.location(i);await _(e,f)&&(l+=1)}catch{}d.length<25&&d.push({id:String(t.id),from:`${t.storage}:${t.filename_disk}`,to_storage:i,to_path:f});const m=u.get(i)||{files:0,bytes:0};m.files+=1,m.bytes+=Number(t.filesize)||0,u.set(i,m)}const f=new Set(s.map(e=>e.folder).filter(Boolean));return{folder_id:e.folderId,mode:e.mode,target_storage:"merge"===e.mode&&e.targetStorage||null,structure_only:Boolean(e.structureOnly),total_files:s.length,total_folders:f.size,total_bytes:s.reduce((e,t)=>e+(Number(t.filesize)||0),0),conflicts:l,samples:d,by_storage:Array.from(u.entries()).map(([e,t])=>({storage:e,files:t.files,bytes:t.bytes}))}}({database:r,folderId:a,mode:s,targetStorage:c||void 0,structureOnly:Boolean(o.structure_only),recursive:Boolean(o.recursive)});t.json({data:l})}catch(e){o(e)}}),e.post("/materialize",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=e.body||{},s="merge"===n.mode?"merge":"preserve",a=void 0===n.folder_id||null===n.folder_id||""===n.folder_id?null:String(n.folder_id),c=String(n.target_storage||"").trim();if("merge"===s&&!c)return void t.status(400).json({errors:[{message:'target_storage is required when mode is "merge"'}]});if("merge"===s){if(!E(i).includes(c))return void t.status(400).json({errors:[{message:`Unknown target storage: ${c}`}]})}const l=await ot({database:r,logger:o,folderId:a,mode:s,targetStorage:c||void 0,structureOnly:Boolean(n.structure_only),keepSourceFileOnDisk:Boolean(n.keep_source_file_on_disk),recursive:Boolean(n.recursive)});t.json({data:l})}catch(e){n(e)}}),e.post("/materialize/stream",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=e.body||{},s="merge"===n.mode?"merge":"preserve",a=void 0===n.folder_id||null===n.folder_id||""===n.folder_id?null:String(n.folder_id),c=String(n.target_storage||"").trim();if("merge"===s&&!c)return void t.status(400).json({errors:[{message:'target_storage is required when mode is "merge"'}]});if("merge"===s){if(!E(i).includes(c))return void t.status(400).json({errors:[{message:`Unknown target storage: ${c}`}]})}t.status(200),t.setHeader("Content-Type","text/event-stream; charset=utf-8"),t.setHeader("Cache-Control","no-cache, no-transform"),t.setHeader("Connection","keep-alive"),t.setHeader("X-Accel-Buffering","no"),t.flushHeaders?.();let l=!1;const u=()=>{l=!0};e.on("close",u),t.on("close",u);const d=e=>{if(l)return;t.write(`data: ${JSON.stringify(e)}\n\n`);const n=t.flush;"function"==typeof n&&n.call(t)};try{await ot({database:r,logger:o,folderId:a,mode:s,targetStorage:c||void 0,structureOnly:Boolean(n.structure_only),keepSourceFileOnDisk:Boolean(n.keep_source_file_on_disk),recursive:Boolean(n.recursive),isCancelled:()=>l,onProgress:e=>d(e)})}catch(e){d({type:"error",message:e instanceof Error?e.message:String(e)})}l||t.end()}catch(e){if(!t.headersSent)return void n(e);try{t.write(`data: ${JSON.stringify({type:"error",message:e instanceof Error?e.message:String(e)})}\n\n`),t.end()}catch{}}}),e.get("/settings",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=await Te(r);t.json({data:{locations:n.locations??{},lifecycle:Oe(n.lifecycle??Ie)}})}catch(e){n(e)}}),e.patch("/settings",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=e.body;if(!n||"object"!=typeof n.locations&&void 0===n.lifecycle)return void t.status(400).json({errors:[{message:'Body must contain a "locations" object and/or "lifecycle".'}]});const i=await r("directus_settings").select(C).first(),o=i?.[C],s="string"==typeof o?JSON.parse(o):o??{locations:{}},a={...s.locations??{}};if(n.locations&&"object"==typeof n.locations)for(const[e,t]of Object.entries(n.locations))a[e]={...D,...s.locations?.[e]??{},...t};const c={locations:a,...void 0!==s.name_mirror_claims?{name_mirror_claims:s.name_mirror_claims}:{},lifecycle:Oe(void 0!==n.lifecycle?{...Oe(s.lifecycle??Ie),...n.lifecycle}:s.lifecycle??Ie)};await r("directus_settings").update({[C]:JSON.stringify(c)}),Ne(),t.json({data:{locations:c.locations,lifecycle:c.lifecycle}})}catch(e){n(e)}}),e.delete("/settings/locations/:location",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location),i=await r("directus_settings").select(C).first(),o=i?.[C],s="string"==typeof o?JSON.parse(o):o??{locations:{}};delete s.locations[n],await r("directus_settings").update({[C]:JSON.stringify(s)}),Ne(),t.json({data:s})}catch(e){n(e)}})}};var Kt={id:"storage-manager-operation",handler:async(e,{env:t,database:n,logger:r})=>{const i="copy"===e.mode?"copy":"move",o=String(e.target_storage||"").trim();if(!o)throw new Error("target_storage is required");const s=E(t);if(!s.includes(o))throw new Error(`Unknown target storage "${o}". Available: ${s.join(", ")}`);let a=function(e){if(!e)return[];if(Array.isArray(e))return e.map(String).filter(Boolean);if("string"==typeof e){const t=e.trim();if(!t)return[];try{const e=JSON.parse(t);if(Array.isArray(e))return e.map(String).filter(Boolean)}catch{return[t]}}return[]}(e.file_ids);if(0===a.length){const t=n("directus_files").select("id");if(e.source_storage){const n=String(e.source_storage).trim();if(!s.includes(n))throw new Error(`Unknown source storage "${n}"`);t.where("storage",n)}if(e.folder_id){const r=await async function(e,t,n){if(!n)return[t];const r=await e("directus_folders").select("id","parent"),i=new Map;for(const e of r){const t=null==e.parent?null:String(e.parent),n=String(e.id);i.has(t)||i.set(t,[]),i.get(t).push(n)}const o=[],s=[String(t)];for(;s.length;){const e=s.pop();o.push(e);for(const t of i.get(e)||[])s.push(t)}return o}(n,String(e.folder_id),!1!==e.recursive);t.whereIn("folder",r)}if(!e.source_storage&&!e.folder_id)throw new Error("Provide file_ids, source_storage, and/or folder_id");a=(await t).map(e=>String(e.id))}const c=null!=e.concurrency?parseInt(String(e.concurrency),10):1;return r.info(`[storage-manager-operation] ${i} ${a.length} file(s) → ${o}`),await fe({fileIds:a,targetStorage:o,mode:i,concurrency:c,database:n,logger:r})}};const Xt=["interface","display","layout","module","panel","theme"],Yt=["hook","endpoint"],Qt=["operation"];function en(e,t,n){function r(n,r){var i;Object.defineProperty(n,"_zod",{value:n._zod??{},enumerable:!1}),(i=n._zod).traits??(i.traits=new Set),n._zod.traits.add(e),t(n,r);for(const e in s.prototype)e in n||Object.defineProperty(n,e,{value:s.prototype[e].bind(n)});n._zod.constr=s,n._zod.def=r}const i=n?.Parent??Object;class o extends i{}function s(e){var t;const i=n?.Parent?new o:this;r(i,e),(t=i._zod).deferred??(t.deferred=[]);for(const e of i._zod.deferred)e();return i}return Object.defineProperty(o,"name",{value:e}),Object.defineProperty(s,"init",{value:r}),Object.defineProperty(s,Symbol.hasInstance,{value:t=>!!(n?.Parent&&t instanceof n.Parent)||t?._zod?.traits?.has(e)}),Object.defineProperty(s,"name",{value:e}),s}class tn extends Error{constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}}class nn extends Error{constructor(e){super(`Encountered unidirectional transform during encode: ${e}`),this.name="ZodEncodeError"}}const rn={};function on(e){return rn}function sn(e,t){return"bigint"==typeof t?t.toString():t}function an(e){return{get value(){{const t=e();return Object.defineProperty(this,"value",{value:t}),t}}}}function cn(e){return null==e}function ln(e){const t=e.startsWith("^")?1:0,n=e.endsWith("$")?e.length-1:e.length;return e.slice(t,n)}const un=Symbol("evaluating");function dn(e,t,n){let r;Object.defineProperty(e,t,{get(){if(r!==un)return void 0===r&&(r=un,r=n()),r},set(n){Object.defineProperty(e,t,{value:n})},configurable:!0})}function fn(e,t,n){Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0})}function pn(...e){const t={};for(const n of e){const e=Object.getOwnPropertyDescriptors(n);Object.assign(t,e)}return Object.defineProperties({},t)}function gn(e){return JSON.stringify(e)}const mn="captureStackTrace"in Error?Error.captureStackTrace:(...e)=>{};function hn(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}const _n=an(()=>{if("undefined"!=typeof navigator&&navigator?.userAgent?.includes("Cloudflare"))return!1;try{return new Function(""),!0}catch(e){return!1}});function yn(e){if(!1===hn(e))return!1;const t=e.constructor;if(void 0===t)return!0;const n=t.prototype;return!1!==hn(n)&&!1!==Object.prototype.hasOwnProperty.call(n,"isPrototypeOf")}function wn(e){return yn(e)?{...e}:Array.isArray(e)?[...e]:e}const vn=new Set(["string","number","symbol"]);function kn(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Sn(e,t,n){const r=new e._zod.constr(t??e._zod.def);return t&&!n?.parent||(r._zod.parent=e),r}function bn(e){const t=e;if(!t)return{};if("string"==typeof t)return{error:()=>t};if(void 0!==t?.message){if(void 0!==t?.error)throw new Error("Cannot specify both `message` and `error` params");t.error=t.message}return delete t.message,"string"==typeof t.error?{...t,error:()=>t.error}:t}function $n(e,t=0){if(!0===e.aborted)return!0;for(let n=t;n<e.issues.length;n++)if(!0!==e.issues[n]?.continue)return!0;return!1}function zn(e,t){return t.map(t=>{var n;return(n=t).path??(n.path=[]),t.path.unshift(e),t})}function jn(e){return"string"==typeof e?e:e?.message}function xn(e,t,n){const r={...e,path:e.path??[]};if(!e.message){const i=jn(e.inst?._zod.def?.error?.(e))??jn(t?.error?.(e))??jn(n.customError?.(e))??jn(n.localeError?.(e))??"Invalid input";r.message=i}return delete r.inst,delete r.continue,t?.reportInput||delete r.input,r}function An(e){return Array.isArray(e)?"array":"string"==typeof e?"string":"unknown"}function En(...e){const[t,n,r]=e;return"string"==typeof t?{message:t,code:"custom",input:n,inst:r}:{...t}}const In=(e,t)=>{e.name="$ZodError",Object.defineProperty(e,"_zod",{value:e._zod,enumerable:!1}),Object.defineProperty(e,"issues",{value:t,enumerable:!1}),e.message=JSON.stringify(t,sn,2),Object.defineProperty(e,"toString",{value:()=>e.message,enumerable:!1})},On=en("$ZodError",In),Pn=en("$ZodError",In,{Parent:Error});const Nn=e=>(t,n,r,i)=>{const o=r?Object.assign(r,{async:!1}):{async:!1},s=t._zod.run({value:n,issues:[]},o);if(s instanceof Promise)throw new tn;if(s.issues.length){const t=new(i?.Err??e)(s.issues.map(e=>xn(e,o,on())));throw mn(t,i?.callee),t}return s.value},Tn=e=>async(t,n,r,i)=>{const o=r?Object.assign(r,{async:!0}):{async:!0};let s=t._zod.run({value:n,issues:[]},o);if(s instanceof Promise&&(s=await s),s.issues.length){const t=new(i?.Err??e)(s.issues.map(e=>xn(e,o,on())));throw mn(t,i?.callee),t}return s.value},Zn=e=>(t,n,r)=>{const i=r?{...r,async:!1}:{async:!1},o=t._zod.run({value:n,issues:[]},i);if(o instanceof Promise)throw new tn;return o.issues.length?{success:!1,error:new(e??On)(o.issues.map(e=>xn(e,i,on())))}:{success:!0,data:o.value}},Cn=Zn(Pn),Fn=e=>async(t,n,r)=>{const i=r?Object.assign(r,{async:!0}):{async:!0};let o=t._zod.run({value:n,issues:[]},i);return o instanceof Promise&&(o=await o),o.issues.length?{success:!1,error:new e(o.issues.map(e=>xn(e,i,on())))}:{success:!0,data:o.value}},Dn=Fn(Pn),Bn=e=>(t,n,r)=>{const i=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Nn(e)(t,n,i)},Un=e=>(t,n,r)=>Nn(e)(t,n,r),Rn=e=>async(t,n,r)=>{const i=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Tn(e)(t,n,i)},Mn=e=>async(t,n,r)=>Tn(e)(t,n,r),qn=e=>(t,n,r)=>{const i=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Zn(e)(t,n,i)},Ln=e=>(t,n,r)=>Zn(e)(t,n,r),Wn=e=>async(t,n,r)=>{const i=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Fn(e)(t,n,i)},Jn=e=>async(t,n,r)=>Fn(e)(t,n,r),Gn=/^[cC][^\s-]{8,}$/,Hn=/^[0-9a-z]+$/,Vn=/^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/,Kn=/^[0-9a-vA-V]{20}$/,Xn=/^[A-Za-z0-9]{27}$/,Yn=/^[a-zA-Z0-9_-]{21}$/,Qn=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/,er=/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/,tr=e=>e?new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${e}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`):/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/,nr=/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/;const rr=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,ir=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/,or=/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/,sr=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,ar=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,cr=/^[A-Za-z0-9_-]*$/,lr=/^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/,ur=/^\+(?:[0-9]){6,14}[0-9]$/,dr="(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))",fr=new RegExp(`^${dr}$`);function pr(e){const t="(?:[01]\\d|2[0-3]):[0-5]\\d";return"number"==typeof e.precision?-1===e.precision?`${t}`:0===e.precision?`${t}:[0-5]\\d`:`${t}:[0-5]\\d\\.\\d{${e.precision}}`:`${t}(?::[0-5]\\d(?:\\.\\d+)?)?`}const gr=/^(?:true|false)$/i,mr=/^[^A-Z]*$/,hr=/^[^a-z]*$/,_r=en("$ZodCheck",(e,t)=>{var n;e._zod??(e._zod={}),e._zod.def=t,(n=e._zod).onattach??(n.onattach=[])}),yr=en("$ZodCheckMaxLength",(e,t)=>{var n;_r.init(e,t),(n=e._zod.def).when??(n.when=e=>{const t=e.value;return!cn(t)&&void 0!==t.length}),e._zod.onattach.push(e=>{const n=e._zod.bag.maximum??Number.POSITIVE_INFINITY;t.maximum<n&&(e._zod.bag.maximum=t.maximum)}),e._zod.check=n=>{const r=n.value;if(r.length<=t.maximum)return;const i=An(r);n.issues.push({origin:i,code:"too_big",maximum:t.maximum,inclusive:!0,input:r,inst:e,continue:!t.abort})}}),wr=en("$ZodCheckMinLength",(e,t)=>{var n;_r.init(e,t),(n=e._zod.def).when??(n.when=e=>{const t=e.value;return!cn(t)&&void 0!==t.length}),e._zod.onattach.push(e=>{const n=e._zod.bag.minimum??Number.NEGATIVE_INFINITY;t.minimum>n&&(e._zod.bag.minimum=t.minimum)}),e._zod.check=n=>{const r=n.value;if(r.length>=t.minimum)return;const i=An(r);n.issues.push({origin:i,code:"too_small",minimum:t.minimum,inclusive:!0,input:r,inst:e,continue:!t.abort})}}),vr=en("$ZodCheckLengthEquals",(e,t)=>{var n;_r.init(e,t),(n=e._zod.def).when??(n.when=e=>{const t=e.value;return!cn(t)&&void 0!==t.length}),e._zod.onattach.push(e=>{const n=e._zod.bag;n.minimum=t.length,n.maximum=t.length,n.length=t.length}),e._zod.check=n=>{const r=n.value,i=r.length;if(i===t.length)return;const o=An(r),s=i>t.length;n.issues.push({origin:o,...s?{code:"too_big",maximum:t.length}:{code:"too_small",minimum:t.length},inclusive:!0,exact:!0,input:n.value,inst:e,continue:!t.abort})}}),kr=en("$ZodCheckStringFormat",(e,t)=>{var n,r;_r.init(e,t),e._zod.onattach.push(e=>{const n=e._zod.bag;n.format=t.format,t.pattern&&(n.patterns??(n.patterns=new Set),n.patterns.add(t.pattern))}),t.pattern?(n=e._zod).check??(n.check=n=>{t.pattern.lastIndex=0,t.pattern.test(n.value)||n.issues.push({origin:"string",code:"invalid_format",format:t.format,input:n.value,...t.pattern?{pattern:t.pattern.toString()}:{},inst:e,continue:!t.abort})}):(r=e._zod).check??(r.check=()=>{})}),Sr=en("$ZodCheckRegex",(e,t)=>{kr.init(e,t),e._zod.check=n=>{t.pattern.lastIndex=0,t.pattern.test(n.value)||n.issues.push({origin:"string",code:"invalid_format",format:"regex",input:n.value,pattern:t.pattern.toString(),inst:e,continue:!t.abort})}}),br=en("$ZodCheckLowerCase",(e,t)=>{t.pattern??(t.pattern=mr),kr.init(e,t)}),$r=en("$ZodCheckUpperCase",(e,t)=>{t.pattern??(t.pattern=hr),kr.init(e,t)}),zr=en("$ZodCheckIncludes",(e,t)=>{_r.init(e,t);const n=kn(t.includes),r=new RegExp("number"==typeof t.position?`^.{${t.position}}${n}`:n);t.pattern=r,e._zod.onattach.push(e=>{const t=e._zod.bag;t.patterns??(t.patterns=new Set),t.patterns.add(r)}),e._zod.check=n=>{n.value.includes(t.includes,t.position)||n.issues.push({origin:"string",code:"invalid_format",format:"includes",includes:t.includes,input:n.value,inst:e,continue:!t.abort})}}),jr=en("$ZodCheckStartsWith",(e,t)=>{_r.init(e,t);const n=new RegExp(`^${kn(t.prefix)}.*`);t.pattern??(t.pattern=n),e._zod.onattach.push(e=>{const t=e._zod.bag;t.patterns??(t.patterns=new Set),t.patterns.add(n)}),e._zod.check=n=>{n.value.startsWith(t.prefix)||n.issues.push({origin:"string",code:"invalid_format",format:"starts_with",prefix:t.prefix,input:n.value,inst:e,continue:!t.abort})}}),xr=en("$ZodCheckEndsWith",(e,t)=>{_r.init(e,t);const n=new RegExp(`.*${kn(t.suffix)}$`);t.pattern??(t.pattern=n),e._zod.onattach.push(e=>{const t=e._zod.bag;t.patterns??(t.patterns=new Set),t.patterns.add(n)}),e._zod.check=n=>{n.value.endsWith(t.suffix)||n.issues.push({origin:"string",code:"invalid_format",format:"ends_with",suffix:t.suffix,input:n.value,inst:e,continue:!t.abort})}}),Ar=en("$ZodCheckOverwrite",(e,t)=>{_r.init(e,t),e._zod.check=e=>{e.value=t.tx(e.value)}});class Er{constructor(e=[]){this.content=[],this.indent=0,this&&(this.args=e)}indented(e){this.indent+=1,e(this),this.indent-=1}write(e){if("function"==typeof e)return e(this,{execution:"sync"}),void e(this,{execution:"async"});const t=e.split("\n").filter(e=>e),n=Math.min(...t.map(e=>e.length-e.trimStart().length)),r=t.map(e=>e.slice(n)).map(e=>" ".repeat(2*this.indent)+e);for(const e of r)this.content.push(e)}compile(){const e=Function,t=this?.args;return new e(...t,[...(this?.content??[""]).map(e=>` ${e}`)].join("\n"))}}const Ir={major:4,minor:1,patch:12},Or=en("$ZodType",(e,t)=>{var n;e??(e={}),e._zod.def=t,e._zod.bag=e._zod.bag||{},e._zod.version=Ir;const r=[...e._zod.def.checks??[]];e._zod.traits.has("$ZodCheck")&&r.unshift(e);for(const t of r)for(const n of t._zod.onattach)n(e);if(0===r.length)(n=e._zod).deferred??(n.deferred=[]),e._zod.deferred?.push(()=>{e._zod.run=e._zod.parse});else{const t=(e,t,n)=>{let r,i=$n(e);for(const o of t){if(o._zod.def.when){if(!o._zod.def.when(e))continue}else if(i)continue;const t=e.issues.length,s=o._zod.check(e);if(s instanceof Promise&&!1===n?.async)throw new tn;if(r||s instanceof Promise)r=(r??Promise.resolve()).then(async()=>{await s;e.issues.length!==t&&(i||(i=$n(e,t)))});else{if(e.issues.length===t)continue;i||(i=$n(e,t))}}return r?r.then(()=>e):e},n=(n,i,o)=>{if($n(n))return n.aborted=!0,n;const s=t(i,r,o);if(s instanceof Promise){if(!1===o.async)throw new tn;return s.then(t=>e._zod.parse(t,o))}return e._zod.parse(s,o)};e._zod.run=(i,o)=>{if(o.skipChecks)return e._zod.parse(i,o);if("backward"===o.direction){const t=e._zod.parse({value:i.value,issues:[]},{...o,skipChecks:!0});return t instanceof Promise?t.then(e=>n(e,i,o)):n(t,i,o)}const s=e._zod.parse(i,o);if(s instanceof Promise){if(!1===o.async)throw new tn;return s.then(e=>t(e,r,o))}return t(s,r,o)}}e["~standard"]={validate:t=>{try{const n=Cn(e,t);return n.success?{value:n.data}:{issues:n.error?.issues}}catch(n){return Dn(e,t).then(e=>e.success?{value:e.data}:{issues:e.error?.issues})}},vendor:"zod",version:1}}),Pr=en("$ZodString",(e,t)=>{var n;Or.init(e,t),e._zod.pattern=[...e?._zod.bag?.patterns??[]].pop()??(n=e._zod.bag,new RegExp(`^${n?`[\\s\\S]{${n?.minimum??0},${n?.maximum??""}}`:"[\\s\\S]*"}$`)),e._zod.parse=(n,r)=>{if(t.coerce)try{n.value=String(n.value)}catch(r){}return"string"==typeof n.value||n.issues.push({expected:"string",code:"invalid_type",input:n.value,inst:e}),n}}),Nr=en("$ZodStringFormat",(e,t)=>{kr.init(e,t),Pr.init(e,t)}),Tr=en("$ZodGUID",(e,t)=>{t.pattern??(t.pattern=er),Nr.init(e,t)}),Zr=en("$ZodUUID",(e,t)=>{if(t.version){const e={v1:1,v2:2,v3:3,v4:4,v5:5,v6:6,v7:7,v8:8}[t.version];if(void 0===e)throw new Error(`Invalid UUID version: "${t.version}"`);t.pattern??(t.pattern=tr(e))}else t.pattern??(t.pattern=tr());Nr.init(e,t)}),Cr=en("$ZodEmail",(e,t)=>{t.pattern??(t.pattern=nr),Nr.init(e,t)}),Fr=en("$ZodURL",(e,t)=>{Nr.init(e,t),e._zod.check=n=>{try{const r=n.value.trim(),i=new URL(r);return t.hostname&&(t.hostname.lastIndex=0,t.hostname.test(i.hostname)||n.issues.push({code:"invalid_format",format:"url",note:"Invalid hostname",pattern:lr.source,input:n.value,inst:e,continue:!t.abort})),t.protocol&&(t.protocol.lastIndex=0,t.protocol.test(i.protocol.endsWith(":")?i.protocol.slice(0,-1):i.protocol)||n.issues.push({code:"invalid_format",format:"url",note:"Invalid protocol",pattern:t.protocol.source,input:n.value,inst:e,continue:!t.abort})),void(t.normalize?n.value=i.href:n.value=r)}catch(r){n.issues.push({code:"invalid_format",format:"url",input:n.value,inst:e,continue:!t.abort})}}}),Dr=en("$ZodEmoji",(e,t)=>{t.pattern??(t.pattern=new RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$","u")),Nr.init(e,t)}),Br=en("$ZodNanoID",(e,t)=>{t.pattern??(t.pattern=Yn),Nr.init(e,t)}),Ur=en("$ZodCUID",(e,t)=>{t.pattern??(t.pattern=Gn),Nr.init(e,t)}),Rr=en("$ZodCUID2",(e,t)=>{t.pattern??(t.pattern=Hn),Nr.init(e,t)}),Mr=en("$ZodULID",(e,t)=>{t.pattern??(t.pattern=Vn),Nr.init(e,t)}),qr=en("$ZodXID",(e,t)=>{t.pattern??(t.pattern=Kn),Nr.init(e,t)}),Lr=en("$ZodKSUID",(e,t)=>{t.pattern??(t.pattern=Xn),Nr.init(e,t)}),Wr=en("$ZodISODateTime",(e,t)=>{t.pattern??(t.pattern=function(e){const t=pr({precision:e.precision}),n=["Z"];e.local&&n.push(""),e.offset&&n.push("([+-](?:[01]\\d|2[0-3]):[0-5]\\d)");const r=`${t}(?:${n.join("|")})`;return new RegExp(`^${dr}T(?:${r})$`)}(t)),Nr.init(e,t)}),Jr=en("$ZodISODate",(e,t)=>{t.pattern??(t.pattern=fr),Nr.init(e,t)}),Gr=en("$ZodISOTime",(e,t)=>{t.pattern??(t.pattern=new RegExp(`^${pr(t)}$`)),Nr.init(e,t)}),Hr=en("$ZodISODuration",(e,t)=>{t.pattern??(t.pattern=Qn),Nr.init(e,t)}),Vr=en("$ZodIPv4",(e,t)=>{t.pattern??(t.pattern=rr),Nr.init(e,t),e._zod.onattach.push(e=>{e._zod.bag.format="ipv4"})}),Kr=en("$ZodIPv6",(e,t)=>{t.pattern??(t.pattern=ir),Nr.init(e,t),e._zod.onattach.push(e=>{e._zod.bag.format="ipv6"}),e._zod.check=n=>{try{new URL(`http://[${n.value}]`)}catch{n.issues.push({code:"invalid_format",format:"ipv6",input:n.value,inst:e,continue:!t.abort})}}}),Xr=en("$ZodCIDRv4",(e,t)=>{t.pattern??(t.pattern=or),Nr.init(e,t)}),Yr=en("$ZodCIDRv6",(e,t)=>{t.pattern??(t.pattern=sr),Nr.init(e,t),e._zod.check=n=>{const r=n.value.split("/");try{if(2!==r.length)throw new Error;const[e,t]=r;if(!t)throw new Error;const n=Number(t);if(`${n}`!==t)throw new Error;if(n<0||n>128)throw new Error;new URL(`http://[${e}]`)}catch{n.issues.push({code:"invalid_format",format:"cidrv6",input:n.value,inst:e,continue:!t.abort})}}});function Qr(e){if(""===e)return!0;if(e.length%4!=0)return!1;try{return atob(e),!0}catch{return!1}}const ei=en("$ZodBase64",(e,t)=>{t.pattern??(t.pattern=ar),Nr.init(e,t),e._zod.onattach.push(e=>{e._zod.bag.contentEncoding="base64"}),e._zod.check=n=>{Qr(n.value)||n.issues.push({code:"invalid_format",format:"base64",input:n.value,inst:e,continue:!t.abort})}});const ti=en("$ZodBase64URL",(e,t)=>{t.pattern??(t.pattern=cr),Nr.init(e,t),e._zod.onattach.push(e=>{e._zod.bag.contentEncoding="base64url"}),e._zod.check=n=>{(function(e){if(!cr.test(e))return!1;const t=e.replace(/[-_]/g,e=>"-"===e?"+":"/");return Qr(t.padEnd(4*Math.ceil(t.length/4),"="))})(n.value)||n.issues.push({code:"invalid_format",format:"base64url",input:n.value,inst:e,continue:!t.abort})}}),ni=en("$ZodE164",(e,t)=>{t.pattern??(t.pattern=ur),Nr.init(e,t)});const ri=en("$ZodJWT",(e,t)=>{Nr.init(e,t),e._zod.check=n=>{(function(e,t=null){try{const n=e.split(".");if(3!==n.length)return!1;const[r]=n;if(!r)return!1;const i=JSON.parse(atob(r));return!("typ"in i&&"JWT"!==i?.typ||!i.alg||t&&(!("alg"in i)||i.alg!==t))}catch{return!1}})(n.value,t.alg)||n.issues.push({code:"invalid_format",format:"jwt",input:n.value,inst:e,continue:!t.abort})}}),ii=en("$ZodBoolean",(e,t)=>{Or.init(e,t),e._zod.pattern=gr,e._zod.parse=(n,r)=>{if(t.coerce)try{n.value=Boolean(n.value)}catch(e){}const i=n.value;return"boolean"==typeof i||n.issues.push({expected:"boolean",code:"invalid_type",input:i,inst:e}),n}}),oi=en("$ZodUnknown",(e,t)=>{Or.init(e,t),e._zod.parse=e=>e}),si=en("$ZodNever",(e,t)=>{Or.init(e,t),e._zod.parse=(t,n)=>(t.issues.push({expected:"never",code:"invalid_type",input:t.value,inst:e}),t)});function ai(e,t,n){e.issues.length&&t.issues.push(...zn(n,e.issues)),t.value[n]=e.value}const ci=en("$ZodArray",(e,t)=>{Or.init(e,t),e._zod.parse=(n,r)=>{const i=n.value;if(!Array.isArray(i))return n.issues.push({expected:"array",code:"invalid_type",input:i,inst:e}),n;n.value=Array(i.length);const o=[];for(let e=0;e<i.length;e++){const s=i[e],a=t.element._zod.run({value:s,issues:[]},r);a instanceof Promise?o.push(a.then(t=>ai(t,n,e))):ai(a,n,e)}return o.length?Promise.all(o).then(()=>n):n}});function li(e,t,n,r){e.issues.length&&t.issues.push(...zn(n,e.issues)),void 0===e.value?n in r&&(t.value[n]=void 0):t.value[n]=e.value}function ui(e){const t=Object.keys(e.shape);for(const n of t)if(!e.shape?.[n]?._zod?.traits?.has("$ZodType"))throw new Error(`Invalid element at key "${n}": expected a Zod schema`);const n=(r=e.shape,Object.keys(r).filter(e=>"optional"===r[e]._zod.optin&&"optional"===r[e]._zod.optout));var r;return{...e,keys:t,keySet:new Set(t),numKeys:t.length,optionalKeys:new Set(n)}}function di(e,t,n,r,i,o){const s=[],a=i.keySet,c=i.catchall._zod,l=c.def.type;for(const i of Object.keys(t)){if(a.has(i))continue;if("never"===l){s.push(i);continue}const o=c.run({value:t[i],issues:[]},r);o instanceof Promise?e.push(o.then(e=>li(e,n,i,t))):li(o,n,i,t)}return s.length&&n.issues.push({code:"unrecognized_keys",keys:s,input:t,inst:o}),e.length?Promise.all(e).then(()=>n):n}const fi=en("$ZodObject",(e,t)=>{Or.init(e,t);const n=Object.getOwnPropertyDescriptor(t,"shape");if(!n?.get){const e=t.shape;Object.defineProperty(t,"shape",{get:()=>{const n={...e};return Object.defineProperty(t,"shape",{value:n}),n}})}const r=an(()=>ui(t));dn(e._zod,"propValues",()=>{const e=t.shape,n={};for(const t in e){const r=e[t]._zod;if(r.values){n[t]??(n[t]=new Set);for(const e of r.values)n[t].add(e)}}return n});const i=hn,o=t.catchall;let s;e._zod.parse=(t,n)=>{s??(s=r.value);const a=t.value;if(!i(a))return t.issues.push({expected:"object",code:"invalid_type",input:a,inst:e}),t;t.value={};const c=[],l=s.shape;for(const e of s.keys){const r=l[e]._zod.run({value:a[e],issues:[]},n);r instanceof Promise?c.push(r.then(n=>li(n,t,e,a))):li(r,t,e,a)}return o?di(c,a,t,n,r.value,e):c.length?Promise.all(c).then(()=>t):t}}),pi=en("$ZodObjectJIT",(e,t)=>{fi.init(e,t);const n=e._zod.parse,r=an(()=>ui(t));let i;const o=hn,s=!rn.jitless,a=s&&_n.value,c=t.catchall;let l;e._zod.parse=(u,d)=>{l??(l=r.value);const f=u.value;return o(f)?s&&a&&!1===d?.async&&!0!==d.jitless?(i||(i=(e=>{const t=new Er(["shape","payload","ctx"]),n=r.value,i=e=>{const t=gn(e);return`shape[${t}]._zod.run({ value: input[${t}], issues: [] }, ctx)`};t.write("const input = payload.value;");const o=Object.create(null);let s=0;for(const e of n.keys)o[e]="key_"+s++;t.write("const newResult = {};");for(const e of n.keys){const n=o[e],r=gn(e);t.write(`const ${n} = ${i(e)};`),t.write(`\n if (${n}.issues.length) {\n payload.issues = payload.issues.concat(${n}.issues.map(iss => ({\n ...iss,\n path: iss.path ? [${r}, ...iss.path] : [${r}]\n })));\n }\n \n \n if (${n}.value === undefined) {\n if (${r} in input) {\n newResult[${r}] = undefined;\n }\n } else {\n newResult[${r}] = ${n}.value;\n }\n \n `)}t.write("payload.value = newResult;"),t.write("return payload;");const a=t.compile();return(t,n)=>a(e,t,n)})(t.shape)),u=i(u,d),c?di([],f,u,d,l,e):u):n(u,d):(u.issues.push({expected:"object",code:"invalid_type",input:f,inst:e}),u)}});function gi(e,t,n,r){for(const n of e)if(0===n.issues.length)return t.value=n.value,t;const i=e.filter(e=>!$n(e));return 1===i.length?(t.value=i[0].value,i[0]):(t.issues.push({code:"invalid_union",input:t.value,inst:n,errors:e.map(e=>e.issues.map(e=>xn(e,r,on())))}),t)}const mi=en("$ZodUnion",(e,t)=>{Or.init(e,t),dn(e._zod,"optin",()=>t.options.some(e=>"optional"===e._zod.optin)?"optional":void 0),dn(e._zod,"optout",()=>t.options.some(e=>"optional"===e._zod.optout)?"optional":void 0),dn(e._zod,"values",()=>{if(t.options.every(e=>e._zod.values))return new Set(t.options.flatMap(e=>Array.from(e._zod.values)))}),dn(e._zod,"pattern",()=>{if(t.options.every(e=>e._zod.pattern)){const e=t.options.map(e=>e._zod.pattern);return new RegExp(`^(${e.map(e=>ln(e.source)).join("|")})$`)}});const n=1===t.options.length,r=t.options[0]._zod.run;e._zod.parse=(i,o)=>{if(n)return r(i,o);let s=!1;const a=[];for(const e of t.options){const t=e._zod.run({value:i.value,issues:[]},o);if(t instanceof Promise)a.push(t),s=!0;else{if(0===t.issues.length)return t;a.push(t)}}return s?Promise.all(a).then(t=>gi(t,i,e,o)):gi(a,i,e,o)}}),hi=en("$ZodIntersection",(e,t)=>{Or.init(e,t),e._zod.parse=(e,n)=>{const r=e.value,i=t.left._zod.run({value:r,issues:[]},n),o=t.right._zod.run({value:r,issues:[]},n);return i instanceof Promise||o instanceof Promise?Promise.all([i,o]).then(([t,n])=>yi(e,t,n)):yi(e,i,o)}});function _i(e,t){if(e===t)return{valid:!0,data:e};if(e instanceof Date&&t instanceof Date&&+e===+t)return{valid:!0,data:e};if(yn(e)&&yn(t)){const n=Object.keys(t),r=Object.keys(e).filter(e=>-1!==n.indexOf(e)),i={...e,...t};for(const n of r){const r=_i(e[n],t[n]);if(!r.valid)return{valid:!1,mergeErrorPath:[n,...r.mergeErrorPath]};i[n]=r.data}return{valid:!0,data:i}}if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return{valid:!1,mergeErrorPath:[]};const n=[];for(let r=0;r<e.length;r++){const i=_i(e[r],t[r]);if(!i.valid)return{valid:!1,mergeErrorPath:[r,...i.mergeErrorPath]};n.push(i.data)}return{valid:!0,data:n}}return{valid:!1,mergeErrorPath:[]}}function yi(e,t,n){if(t.issues.length&&e.issues.push(...t.issues),n.issues.length&&e.issues.push(...n.issues),$n(e))return e;const r=_i(t.value,n.value);if(!r.valid)throw new Error(`Unmergable intersection. Error path: ${JSON.stringify(r.mergeErrorPath)}`);return e.value=r.data,e}const wi=en("$ZodRecord",(e,t)=>{Or.init(e,t),e._zod.parse=(n,r)=>{const i=n.value;if(!yn(i))return n.issues.push({expected:"record",code:"invalid_type",input:i,inst:e}),n;const o=[];if(t.keyType._zod.values){const s=t.keyType._zod.values;n.value={};for(const e of s)if("string"==typeof e||"number"==typeof e||"symbol"==typeof e){const s=t.valueType._zod.run({value:i[e],issues:[]},r);s instanceof Promise?o.push(s.then(t=>{t.issues.length&&n.issues.push(...zn(e,t.issues)),n.value[e]=t.value})):(s.issues.length&&n.issues.push(...zn(e,s.issues)),n.value[e]=s.value)}let a;for(const e in i)s.has(e)||(a=a??[],a.push(e));a&&a.length>0&&n.issues.push({code:"unrecognized_keys",input:i,inst:e,keys:a})}else{n.value={};for(const s of Reflect.ownKeys(i)){if("__proto__"===s)continue;const a=t.keyType._zod.run({value:s,issues:[]},r);if(a instanceof Promise)throw new Error("Async schemas not supported in object keys currently");if(a.issues.length){n.issues.push({code:"invalid_key",origin:"record",issues:a.issues.map(e=>xn(e,r,on())),input:s,path:[s],inst:e}),n.value[a.value]=a.value;continue}const c=t.valueType._zod.run({value:i[s],issues:[]},r);c instanceof Promise?o.push(c.then(e=>{e.issues.length&&n.issues.push(...zn(s,e.issues)),n.value[a.value]=e.value})):(c.issues.length&&n.issues.push(...zn(s,c.issues)),n.value[a.value]=c.value)}}return o.length?Promise.all(o).then(()=>n):n}}),vi=en("$ZodEnum",(e,t)=>{Or.init(e,t);const n=function(e){const t=Object.values(e).filter(e=>"number"==typeof e);return Object.entries(e).filter(([e,n])=>-1===t.indexOf(+e)).map(([e,t])=>t)}(t.entries),r=new Set(n);e._zod.values=r,e._zod.pattern=new RegExp(`^(${n.filter(e=>vn.has(typeof e)).map(e=>"string"==typeof e?kn(e):e.toString()).join("|")})$`),e._zod.parse=(t,i)=>{const o=t.value;return r.has(o)||t.issues.push({code:"invalid_value",values:n,input:o,inst:e}),t}}),ki=en("$ZodLiteral",(e,t)=>{if(Or.init(e,t),0===t.values.length)throw new Error("Cannot create literal schema with no valid values");e._zod.values=new Set(t.values),e._zod.pattern=new RegExp(`^(${t.values.map(e=>"string"==typeof e?kn(e):e?kn(e.toString()):String(e)).join("|")})$`),e._zod.parse=(n,r)=>{const i=n.value;return e._zod.values.has(i)||n.issues.push({code:"invalid_value",values:t.values,input:i,inst:e}),n}}),Si=en("$ZodTransform",(e,t)=>{Or.init(e,t),e._zod.parse=(n,r)=>{if("backward"===r.direction)throw new nn(e.constructor.name);const i=t.transform(n.value,n);if(r.async){return(i instanceof Promise?i:Promise.resolve(i)).then(e=>(n.value=e,n))}if(i instanceof Promise)throw new tn;return n.value=i,n}});function bi(e,t){return e.issues.length&&void 0===t?{issues:[],value:void 0}:e}const $i=en("$ZodOptional",(e,t)=>{Or.init(e,t),e._zod.optin="optional",e._zod.optout="optional",dn(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),dn(e._zod,"pattern",()=>{const e=t.innerType._zod.pattern;return e?new RegExp(`^(${ln(e.source)})?$`):void 0}),e._zod.parse=(e,n)=>{if("optional"===t.innerType._zod.optin){const r=t.innerType._zod.run(e,n);return r instanceof Promise?r.then(t=>bi(t,e.value)):bi(r,e.value)}return void 0===e.value?e:t.innerType._zod.run(e,n)}}),zi=en("$ZodNullable",(e,t)=>{Or.init(e,t),dn(e._zod,"optin",()=>t.innerType._zod.optin),dn(e._zod,"optout",()=>t.innerType._zod.optout),dn(e._zod,"pattern",()=>{const e=t.innerType._zod.pattern;return e?new RegExp(`^(${ln(e.source)}|null)$`):void 0}),dn(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,null]):void 0),e._zod.parse=(e,n)=>null===e.value?e:t.innerType._zod.run(e,n)}),ji=en("$ZodDefault",(e,t)=>{Or.init(e,t),e._zod.optin="optional",dn(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(e,n)=>{if("backward"===n.direction)return t.innerType._zod.run(e,n);if(void 0===e.value)return e.value=t.defaultValue,e;const r=t.innerType._zod.run(e,n);return r instanceof Promise?r.then(e=>xi(e,t)):xi(r,t)}});function xi(e,t){return void 0===e.value&&(e.value=t.defaultValue),e}const Ai=en("$ZodPrefault",(e,t)=>{Or.init(e,t),e._zod.optin="optional",dn(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(e,n)=>("backward"===n.direction||void 0===e.value&&(e.value=t.defaultValue),t.innerType._zod.run(e,n))}),Ei=en("$ZodNonOptional",(e,t)=>{Or.init(e,t),dn(e._zod,"values",()=>{const e=t.innerType._zod.values;return e?new Set([...e].filter(e=>void 0!==e)):void 0}),e._zod.parse=(n,r)=>{const i=t.innerType._zod.run(n,r);return i instanceof Promise?i.then(t=>Ii(t,e)):Ii(i,e)}});function Ii(e,t){return e.issues.length||void 0!==e.value||e.issues.push({code:"invalid_type",expected:"nonoptional",input:e.value,inst:t}),e}const Oi=en("$ZodCatch",(e,t)=>{Or.init(e,t),dn(e._zod,"optin",()=>t.innerType._zod.optin),dn(e._zod,"optout",()=>t.innerType._zod.optout),dn(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(e,n)=>{if("backward"===n.direction)return t.innerType._zod.run(e,n);const r=t.innerType._zod.run(e,n);return r instanceof Promise?r.then(r=>(e.value=r.value,r.issues.length&&(e.value=t.catchValue({...e,error:{issues:r.issues.map(e=>xn(e,n,on()))},input:e.value}),e.issues=[]),e)):(e.value=r.value,r.issues.length&&(e.value=t.catchValue({...e,error:{issues:r.issues.map(e=>xn(e,n,on()))},input:e.value}),e.issues=[]),e)}}),Pi=en("$ZodPipe",(e,t)=>{Or.init(e,t),dn(e._zod,"values",()=>t.in._zod.values),dn(e._zod,"optin",()=>t.in._zod.optin),dn(e._zod,"optout",()=>t.out._zod.optout),dn(e._zod,"propValues",()=>t.in._zod.propValues),e._zod.parse=(e,n)=>{if("backward"===n.direction){const r=t.out._zod.run(e,n);return r instanceof Promise?r.then(e=>Ni(e,t.in,n)):Ni(r,t.in,n)}const r=t.in._zod.run(e,n);return r instanceof Promise?r.then(e=>Ni(e,t.out,n)):Ni(r,t.out,n)}});function Ni(e,t,n){return e.issues.length?(e.aborted=!0,e):t._zod.run({value:e.value,issues:e.issues},n)}const Ti=en("$ZodReadonly",(e,t)=>{Or.init(e,t),dn(e._zod,"propValues",()=>t.innerType._zod.propValues),dn(e._zod,"values",()=>t.innerType._zod.values),dn(e._zod,"optin",()=>t.innerType._zod.optin),dn(e._zod,"optout",()=>t.innerType._zod.optout),e._zod.parse=(e,n)=>{if("backward"===n.direction)return t.innerType._zod.run(e,n);const r=t.innerType._zod.run(e,n);return r instanceof Promise?r.then(Zi):Zi(r)}});function Zi(e){return e.value=Object.freeze(e.value),e}const Ci=en("$ZodCustom",(e,t)=>{_r.init(e,t),Or.init(e,t),e._zod.parse=(e,t)=>e,e._zod.check=n=>{const r=n.value,i=t.fn(r);if(i instanceof Promise)return i.then(t=>Fi(t,n,r,e));Fi(i,n,r,e)}});function Fi(e,t,n,r){if(!e){const e={code:"custom",input:n,inst:r,path:[...r._zod.def.path??[]],continue:!r._zod.def.abort};r._zod.def.params&&(e.params=r._zod.def.params),t.issues.push(En(e))}}class Di{constructor(){this._map=new WeakMap,this._idmap=new Map}add(e,...t){const n=t[0];if(this._map.set(e,n),n&&"object"==typeof n&&"id"in n){if(this._idmap.has(n.id))throw new Error(`ID ${n.id} already exists in the registry`);this._idmap.set(n.id,e)}return this}clear(){return this._map=new WeakMap,this._idmap=new Map,this}remove(e){const t=this._map.get(e);return t&&"object"==typeof t&&"id"in t&&this._idmap.delete(t.id),this._map.delete(e),this}get(e){const t=e._zod.parent;if(t){const n={...this.get(t)??{}};delete n.id;const r={...n,...this._map.get(e)};return Object.keys(r).length?r:void 0}return this._map.get(e)}has(e){return this._map.has(e)}}function Bi(){return new Di}const Ui=Bi();function Ri(e,t){return new e({type:"string",format:"guid",check:"string_format",abort:!1,...bn(t)})}function Mi(e,t){return new yr({check:"max_length",...bn(t),maximum:e})}function qi(e,t){return new wr({check:"min_length",...bn(t),minimum:e})}function Li(e,t){return new vr({check:"length_equals",...bn(t),length:e})}function Wi(e){return new Ar({check:"overwrite",tx:e})}function Ji(e){const t=function(e,t){const n=new _r({check:"custom",...bn(t)});return n._zod.check=e,n}(n=>(n.addIssue=e=>{if("string"==typeof e)n.issues.push(En(e,n.value,t._zod.def));else{const r=e;r.fatal&&(r.continue=!1),r.code??(r.code="custom"),r.input??(r.input=n.value),r.inst??(r.inst=t),r.continue??(r.continue=!t._zod.def.abort),n.issues.push(En(r))}},e(n.value,n)));return t}const Gi=en("ZodISODateTime",(e,t)=>{Wr.init(e,t),wo.init(e,t)});function Hi(e){return function(e,t){return new e({type:"string",format:"datetime",check:"string_format",offset:!1,local:!1,precision:null,...bn(t)})}(Gi,e)}const Vi=en("ZodISODate",(e,t)=>{Jr.init(e,t),wo.init(e,t)});function Ki(e){return function(e,t){return new e({type:"string",format:"date",check:"string_format",...bn(t)})}(Vi,e)}const Xi=en("ZodISOTime",(e,t)=>{Gr.init(e,t),wo.init(e,t)});function Yi(e){return function(e,t){return new e({type:"string",format:"time",check:"string_format",precision:null,...bn(t)})}(Xi,e)}const Qi=en("ZodISODuration",(e,t)=>{Hr.init(e,t),wo.init(e,t)});function eo(e){return function(e,t){return new e({type:"string",format:"duration",check:"string_format",...bn(t)})}(Qi,e)}const to=en("ZodError",(e,t)=>{On.init(e,t),e.name="ZodError",Object.defineProperties(e,{format:{value:t=>function(e,t=e=>e.message){const n={_errors:[]},r=e=>{for(const i of e.issues)if("invalid_union"===i.code&&i.errors.length)i.errors.map(e=>r({issues:e}));else if("invalid_key"===i.code)r({issues:i.issues});else if("invalid_element"===i.code)r({issues:i.issues});else if(0===i.path.length)n._errors.push(t(i));else{let e=n,r=0;for(;r<i.path.length;){const n=i.path[r];r===i.path.length-1?(e[n]=e[n]||{_errors:[]},e[n]._errors.push(t(i))):e[n]=e[n]||{_errors:[]},e=e[n],r++}}};return r(e),n}(e,t)},flatten:{value:t=>function(e,t=e=>e.message){const n={},r=[];for(const i of e.issues)i.path.length>0?(n[i.path[0]]=n[i.path[0]]||[],n[i.path[0]].push(t(i))):r.push(t(i));return{formErrors:r,fieldErrors:n}}(e,t)},addIssue:{value:t=>{e.issues.push(t),e.message=JSON.stringify(e.issues,sn,2)}},addIssues:{value:t=>{e.issues.push(...t),e.message=JSON.stringify(e.issues,sn,2)}},isEmpty:{get:()=>0===e.issues.length}})},{Parent:Error}),no=Nn(to),ro=Tn(to),io=Zn(to),oo=Fn(to),so=Bn(to),ao=Un(to),co=Rn(to),lo=Mn(to),uo=qn(to),fo=Ln(to),po=Wn(to),go=Jn(to),mo=en("ZodType",(e,t)=>(Or.init(e,t),e.def=t,e.type=t.type,Object.defineProperty(e,"_def",{value:t}),e.check=(...n)=>e.clone(pn(t,{checks:[...t.checks??[],...n.map(e=>"function"==typeof e?{_zod:{check:e,def:{check:"custom"},onattach:[]}}:e)]})),e.clone=(t,n)=>Sn(e,t,n),e.brand=()=>e,e.register=(t,n)=>(t.add(e,n),e),e.parse=(t,n)=>no(e,t,n,{callee:e.parse}),e.safeParse=(t,n)=>io(e,t,n),e.parseAsync=async(t,n)=>ro(e,t,n,{callee:e.parseAsync}),e.safeParseAsync=async(t,n)=>oo(e,t,n),e.spa=e.safeParseAsync,e.encode=(t,n)=>so(e,t,n),e.decode=(t,n)=>ao(e,t,n),e.encodeAsync=async(t,n)=>co(e,t,n),e.decodeAsync=async(t,n)=>lo(e,t,n),e.safeEncode=(t,n)=>uo(e,t,n),e.safeDecode=(t,n)=>fo(e,t,n),e.safeEncodeAsync=async(t,n)=>po(e,t,n),e.safeDecodeAsync=async(t,n)=>go(e,t,n),e.refine=(t,n)=>e.check(function(e,t={}){return function(e,t,n){return new e({type:"custom",check:"custom",fn:t,...bn(n)})}(hs,e,t)}(t,n)),e.superRefine=t=>e.check(Ji(t)),e.overwrite=t=>e.check(Wi(t)),e.optional=()=>ss(e),e.nullable=()=>cs(e),e.nullish=()=>ss(cs(e)),e.nonoptional=t=>function(e,t){return new ds({type:"nonoptional",innerType:e,...bn(t)})}(e,t),e.array=()=>Jo(e),e.or=t=>Ko([e,t]),e.and=t=>new Xo({type:"intersection",left:e,right:t}),e.transform=t=>gs(e,new is({type:"transform",transform:t})),e.default=t=>{return n=t,new ls({type:"default",innerType:e,get defaultValue(){return"function"==typeof n?n():wn(n)}});var n},e.prefault=t=>{return n=t,new us({type:"prefault",innerType:e,get defaultValue(){return"function"==typeof n?n():wn(n)}});var n},e.catch=t=>{return new fs({type:"catch",innerType:e,catchValue:"function"==typeof(n=t)?n:()=>n});var n},e.pipe=t=>gs(e,t),e.readonly=()=>new ms({type:"readonly",innerType:e}),e.describe=t=>{const n=e.clone();return Ui.add(n,{description:t}),n},Object.defineProperty(e,"description",{get:()=>Ui.get(e)?.description,configurable:!0}),e.meta=(...t)=>{if(0===t.length)return Ui.get(e);const n=e.clone();return Ui.add(n,t[0]),n},e.isOptional=()=>e.safeParse(void 0).success,e.isNullable=()=>e.safeParse(null).success,e)),ho=en("_ZodString",(e,t)=>{Pr.init(e,t),mo.init(e,t);const n=e._zod.bag;e.format=n.format??null,e.minLength=n.minimum??null,e.maxLength=n.maximum??null,e.regex=(...t)=>e.check(function(e,t){return new Sr({check:"string_format",format:"regex",...bn(t),pattern:e})}(...t)),e.includes=(...t)=>e.check(function(e,t){return new zr({check:"string_format",format:"includes",...bn(t),includes:e})}(...t)),e.startsWith=(...t)=>e.check(function(e,t){return new jr({check:"string_format",format:"starts_with",...bn(t),prefix:e})}(...t)),e.endsWith=(...t)=>e.check(function(e,t){return new xr({check:"string_format",format:"ends_with",...bn(t),suffix:e})}(...t)),e.min=(...t)=>e.check(qi(...t)),e.max=(...t)=>e.check(Mi(...t)),e.length=(...t)=>e.check(Li(...t)),e.nonempty=(...t)=>e.check(qi(1,...t)),e.lowercase=t=>e.check(function(e){return new br({check:"string_format",format:"lowercase",...bn(e)})}(t)),e.uppercase=t=>e.check(function(e){return new $r({check:"string_format",format:"uppercase",...bn(e)})}(t)),e.trim=()=>e.check(Wi(e=>e.trim())),e.normalize=(...t)=>e.check(function(e){return Wi(t=>t.normalize(e))}(...t)),e.toLowerCase=()=>e.check(Wi(e=>e.toLowerCase())),e.toUpperCase=()=>e.check(Wi(e=>e.toUpperCase()))}),_o=en("ZodString",(e,t)=>{Pr.init(e,t),ho.init(e,t),e.email=t=>e.check(function(e,t){return new e({type:"string",format:"email",check:"string_format",abort:!1,...bn(t)})}(vo,t)),e.url=t=>e.check(function(e,t){return new e({type:"string",format:"url",check:"string_format",abort:!1,...bn(t)})}(bo,t)),e.jwt=t=>e.check(function(e,t){return new e({type:"string",format:"jwt",check:"string_format",abort:!1,...bn(t)})}(Do,t)),e.emoji=t=>e.check(function(e,t){return new e({type:"string",format:"emoji",check:"string_format",abort:!1,...bn(t)})}($o,t)),e.guid=t=>e.check(Ri(ko,t)),e.uuid=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,...bn(t)})}(So,t)),e.uuidv4=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v4",...bn(t)})}(So,t)),e.uuidv6=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v6",...bn(t)})}(So,t)),e.uuidv7=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v7",...bn(t)})}(So,t)),e.nanoid=t=>e.check(function(e,t){return new e({type:"string",format:"nanoid",check:"string_format",abort:!1,...bn(t)})}(zo,t)),e.guid=t=>e.check(Ri(ko,t)),e.cuid=t=>e.check(function(e,t){return new e({type:"string",format:"cuid",check:"string_format",abort:!1,...bn(t)})}(jo,t)),e.cuid2=t=>e.check(function(e,t){return new e({type:"string",format:"cuid2",check:"string_format",abort:!1,...bn(t)})}(xo,t)),e.ulid=t=>e.check(function(e,t){return new e({type:"string",format:"ulid",check:"string_format",abort:!1,...bn(t)})}(Ao,t)),e.base64=t=>e.check(function(e,t){return new e({type:"string",format:"base64",check:"string_format",abort:!1,...bn(t)})}(Zo,t)),e.base64url=t=>e.check(function(e,t){return new e({type:"string",format:"base64url",check:"string_format",abort:!1,...bn(t)})}(Co,t)),e.xid=t=>e.check(function(e,t){return new e({type:"string",format:"xid",check:"string_format",abort:!1,...bn(t)})}(Eo,t)),e.ksuid=t=>e.check(function(e,t){return new e({type:"string",format:"ksuid",check:"string_format",abort:!1,...bn(t)})}(Io,t)),e.ipv4=t=>e.check(function(e,t){return new e({type:"string",format:"ipv4",check:"string_format",abort:!1,...bn(t)})}(Oo,t)),e.ipv6=t=>e.check(function(e,t){return new e({type:"string",format:"ipv6",check:"string_format",abort:!1,...bn(t)})}(Po,t)),e.cidrv4=t=>e.check(function(e,t){return new e({type:"string",format:"cidrv4",check:"string_format",abort:!1,...bn(t)})}(No,t)),e.cidrv6=t=>e.check(function(e,t){return new e({type:"string",format:"cidrv6",check:"string_format",abort:!1,...bn(t)})}(To,t)),e.e164=t=>e.check(function(e,t){return new e({type:"string",format:"e164",check:"string_format",abort:!1,...bn(t)})}(Fo,t)),e.datetime=t=>e.check(Hi(t)),e.date=t=>e.check(Ki(t)),e.time=t=>e.check(Yi(t)),e.duration=t=>e.check(eo(t))});function yo(e){return function(e,t){return new e({type:"string",...bn(t)})}(_o,e)}const wo=en("ZodStringFormat",(e,t)=>{Nr.init(e,t),ho.init(e,t)}),vo=en("ZodEmail",(e,t)=>{Cr.init(e,t),wo.init(e,t)}),ko=en("ZodGUID",(e,t)=>{Tr.init(e,t),wo.init(e,t)}),So=en("ZodUUID",(e,t)=>{Zr.init(e,t),wo.init(e,t)}),bo=en("ZodURL",(e,t)=>{Fr.init(e,t),wo.init(e,t)}),$o=en("ZodEmoji",(e,t)=>{Dr.init(e,t),wo.init(e,t)}),zo=en("ZodNanoID",(e,t)=>{Br.init(e,t),wo.init(e,t)}),jo=en("ZodCUID",(e,t)=>{Ur.init(e,t),wo.init(e,t)}),xo=en("ZodCUID2",(e,t)=>{Rr.init(e,t),wo.init(e,t)}),Ao=en("ZodULID",(e,t)=>{Mr.init(e,t),wo.init(e,t)}),Eo=en("ZodXID",(e,t)=>{qr.init(e,t),wo.init(e,t)}),Io=en("ZodKSUID",(e,t)=>{Lr.init(e,t),wo.init(e,t)}),Oo=en("ZodIPv4",(e,t)=>{Vr.init(e,t),wo.init(e,t)}),Po=en("ZodIPv6",(e,t)=>{Kr.init(e,t),wo.init(e,t)}),No=en("ZodCIDRv4",(e,t)=>{Xr.init(e,t),wo.init(e,t)}),To=en("ZodCIDRv6",(e,t)=>{Yr.init(e,t),wo.init(e,t)}),Zo=en("ZodBase64",(e,t)=>{ei.init(e,t),wo.init(e,t)}),Co=en("ZodBase64URL",(e,t)=>{ti.init(e,t),wo.init(e,t)}),Fo=en("ZodE164",(e,t)=>{ni.init(e,t),wo.init(e,t)}),Do=en("ZodJWT",(e,t)=>{ri.init(e,t),wo.init(e,t)}),Bo=en("ZodBoolean",(e,t)=>{ii.init(e,t),mo.init(e,t)});function Uo(e){return function(e,t){return new e({type:"boolean",...bn(t)})}(Bo,e)}const Ro=en("ZodUnknown",(e,t)=>{oi.init(e,t),mo.init(e,t)});function Mo(){return new Ro({type:"unknown"})}const qo=en("ZodNever",(e,t)=>{si.init(e,t),mo.init(e,t)});function Lo(e){return function(e,t){return new e({type:"never",...bn(t)})}(qo,e)}const Wo=en("ZodArray",(e,t)=>{ci.init(e,t),mo.init(e,t),e.element=t.element,e.min=(t,n)=>e.check(qi(t,n)),e.nonempty=t=>e.check(qi(1,t)),e.max=(t,n)=>e.check(Mi(t,n)),e.length=(t,n)=>e.check(Li(t,n)),e.unwrap=()=>e.element});function Jo(e,t){return function(e,t,n){return new e({type:"array",element:t,...bn(n)})}(Wo,e,t)}const Go=en("ZodObject",(e,t)=>{pi.init(e,t),mo.init(e,t),dn(e,"shape",()=>t.shape),e.keyof=()=>ts(Object.keys(e._zod.def.shape)),e.catchall=t=>e.clone({...e._zod.def,catchall:t}),e.passthrough=()=>e.clone({...e._zod.def,catchall:Mo()}),e.loose=()=>e.clone({...e._zod.def,catchall:Mo()}),e.strict=()=>e.clone({...e._zod.def,catchall:Lo()}),e.strip=()=>e.clone({...e._zod.def,catchall:void 0}),e.extend=t=>function(e,t){if(!yn(t))throw new Error("Invalid input to extend: expected a plain object");const n=e._zod.def.checks;if(n&&n.length>0)throw new Error("Object schemas containing refinements cannot be extended. Use `.safeExtend()` instead.");const r=pn(e._zod.def,{get shape(){const n={...e._zod.def.shape,...t};return fn(this,"shape",n),n},checks:[]});return Sn(e,r)}(e,t),e.safeExtend=t=>function(e,t){if(!yn(t))throw new Error("Invalid input to safeExtend: expected a plain object");const n={...e._zod.def,get shape(){const n={...e._zod.def.shape,...t};return fn(this,"shape",n),n},checks:e._zod.def.checks};return Sn(e,n)}(e,t),e.merge=t=>function(e,t){const n=pn(e._zod.def,{get shape(){const n={...e._zod.def.shape,...t._zod.def.shape};return fn(this,"shape",n),n},get catchall(){return t._zod.def.catchall},checks:[]});return Sn(e,n)}(e,t),e.pick=t=>function(e,t){const n=e._zod.def;return Sn(e,pn(e._zod.def,{get shape(){const e={};for(const r in t){if(!(r in n.shape))throw new Error(`Unrecognized key: "${r}"`);t[r]&&(e[r]=n.shape[r])}return fn(this,"shape",e),e},checks:[]}))}(e,t),e.omit=t=>function(e,t){const n=e._zod.def,r=pn(e._zod.def,{get shape(){const r={...e._zod.def.shape};for(const e in t){if(!(e in n.shape))throw new Error(`Unrecognized key: "${e}"`);t[e]&&delete r[e]}return fn(this,"shape",r),r},checks:[]});return Sn(e,r)}(e,t),e.partial=(...t)=>function(e,t,n){const r=pn(t._zod.def,{get shape(){const r=t._zod.def.shape,i={...r};if(n)for(const t in n){if(!(t in r))throw new Error(`Unrecognized key: "${t}"`);n[t]&&(i[t]=e?new e({type:"optional",innerType:r[t]}):r[t])}else for(const t in r)i[t]=e?new e({type:"optional",innerType:r[t]}):r[t];return fn(this,"shape",i),i},checks:[]});return Sn(t,r)}(os,e,t[0]),e.required=(...t)=>function(e,t,n){const r=pn(t._zod.def,{get shape(){const r=t._zod.def.shape,i={...r};if(n)for(const t in n){if(!(t in i))throw new Error(`Unrecognized key: "${t}"`);n[t]&&(i[t]=new e({type:"nonoptional",innerType:r[t]}))}else for(const t in r)i[t]=new e({type:"nonoptional",innerType:r[t]});return fn(this,"shape",i),i},checks:[]});return Sn(t,r)}(ds,e,t[0])});function Ho(e,t){const n={type:"object",shape:e??{},...bn(t)};return new Go(n)}const Vo=en("ZodUnion",(e,t)=>{mi.init(e,t),mo.init(e,t),e.options=t.options});function Ko(e,t){return new Vo({type:"union",options:e,...bn(t)})}const Xo=en("ZodIntersection",(e,t)=>{hi.init(e,t),mo.init(e,t)});const Yo=en("ZodRecord",(e,t)=>{wi.init(e,t),mo.init(e,t),e.keyType=t.keyType,e.valueType=t.valueType});function Qo(e,t,n){return new Yo({type:"record",keyType:e,valueType:t,...bn(n)})}const es=en("ZodEnum",(e,t)=>{vi.init(e,t),mo.init(e,t),e.enum=t.entries,e.options=Object.values(t.entries);const n=new Set(Object.keys(t.entries));e.extract=(e,r)=>{const i={};for(const r of e){if(!n.has(r))throw new Error(`Key ${r} not found in enum`);i[r]=t.entries[r]}return new es({...t,checks:[],...bn(r),entries:i})},e.exclude=(e,r)=>{const i={...t.entries};for(const t of e){if(!n.has(t))throw new Error(`Key ${t} not found in enum`);delete i[t]}return new es({...t,checks:[],...bn(r),entries:i})}});function ts(e,t){const n=Array.isArray(e)?Object.fromEntries(e.map(e=>[e,e])):e;return new es({type:"enum",entries:n,...bn(t)})}const ns=en("ZodLiteral",(e,t)=>{ki.init(e,t),mo.init(e,t),e.values=new Set(t.values),Object.defineProperty(e,"value",{get(){if(t.values.length>1)throw new Error("This schema contains multiple valid literal values. Use `.values` instead.");return t.values[0]}})});function rs(e,t){return new ns({type:"literal",values:Array.isArray(e)?e:[e],...bn(t)})}const is=en("ZodTransform",(e,t)=>{Si.init(e,t),mo.init(e,t),e._zod.parse=(n,r)=>{if("backward"===r.direction)throw new nn(e.constructor.name);n.addIssue=r=>{if("string"==typeof r)n.issues.push(En(r,n.value,t));else{const t=r;t.fatal&&(t.continue=!1),t.code??(t.code="custom"),t.input??(t.input=n.value),t.inst??(t.inst=e),n.issues.push(En(t))}};const i=t.transform(n.value,n);return i instanceof Promise?i.then(e=>(n.value=e,n)):(n.value=i,n)}});const os=en("ZodOptional",(e,t)=>{$i.init(e,t),mo.init(e,t),e.unwrap=()=>e._zod.def.innerType});function ss(e){return new os({type:"optional",innerType:e})}const as=en("ZodNullable",(e,t)=>{zi.init(e,t),mo.init(e,t),e.unwrap=()=>e._zod.def.innerType});function cs(e){return new as({type:"nullable",innerType:e})}const ls=en("ZodDefault",(e,t)=>{ji.init(e,t),mo.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeDefault=e.unwrap});const us=en("ZodPrefault",(e,t)=>{Ai.init(e,t),mo.init(e,t),e.unwrap=()=>e._zod.def.innerType});const ds=en("ZodNonOptional",(e,t)=>{Ei.init(e,t),mo.init(e,t),e.unwrap=()=>e._zod.def.innerType});const fs=en("ZodCatch",(e,t)=>{Oi.init(e,t),mo.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeCatch=e.unwrap});const ps=en("ZodPipe",(e,t)=>{Pi.init(e,t),mo.init(e,t),e.in=t.in,e.out=t.out});function gs(e,t){return new ps({type:"pipe",in:e,out:t})}const ms=en("ZodReadonly",(e,t)=>{Ti.init(e,t),mo.init(e,t),e.unwrap=()=>e._zod.def.innerType});const hs=en("ZodCustom",(e,t)=>{Ci.init(e,t),mo.init(e,t)});const _s="directus:extension",ys=Ho({app:yo(),api:yo()}),ws=Ho({request:ss(Ho({urls:Jo(yo()),methods:Jo(Ko([rs("GET"),rs("POST"),rs("PATCH"),rs("PUT"),rs("DELETE")]))})),log:ss(Ho({})),sleep:ss(Ho({}))}),vs=ss(Ho({enabled:Uo(),requestedScopes:ws})),ks=Ko([Ho({type:ts(Yt),name:yo(),source:yo()}),Ho({type:ts(Xt),name:yo(),source:yo()}),Ho({type:ts(Qt),name:yo(),source:ys})]),Ss=Ho({host:yo(),hidden:Uo().optional()}),bs=Ho({type:ts(Xt),path:yo(),source:yo()}),$s=Ho({type:ts(Yt),path:yo(),source:yo(),sandbox:vs}),zs=Ho({type:ts(Qt),path:ys,source:ys,sandbox:vs}),js=Ho({type:rs("bundle"),partial:Uo().optional(),path:ys,entries:Jo(ks)});Jo(ks);const xs=Ss.and(Ko([bs,$s,zs,js]));Ho({name:yo(),version:yo(),type:Ko([rs("module"),rs("commonjs")]).optional(),description:yo().optional(),icon:yo().optional(),dependencies:Qo(yo(),yo()).optional(),devDependencies:Qo(yo(),yo()).optional(),[_s]:xs});function As(e){return Object.entries(e).filter(([,e])=>Ke(e)&&He(e.prefix_strategy)).map(([e])=>e)}async function Es(e,t,n,r,i){if(n&&n!==r)for(const o of t)try{const t=await e("directus_files").count({c:"*"}).where("storage",o).whereRaw("filename_disk LIKE ?",[`${n}/%`]).first(),s=Number(t?.c??0);s>=100&&i.warn(`[storage-manager] Folder path sync on ${o}: relocating ${s} files (“${n}” → “${r||"(root)"}”) — this may take a while`);const{moved:a,failed:c}=await se(e,o,n,r,i);(a||c)&&i.info(`[storage-manager] Folder path sync on ${o}: "${n}" → "${r||"(root)"}" (moved=${a}, failed=${c})`)}catch(e){i.error(`[storage-manager] Folder path sync failed for ${o}: ${e?.message}`)}}async function Is(e,t,n){const r={},i={},o=await t("directus_folders").select("id","parent").where("id",e).first(),s=o?.parent?String(o.parent):null;for(const o of(a=n,Object.entries(a).filter(([,e])=>Ke(e)).map(([e])=>e))){const a=n[o];let c=null,l="";He(a.prefix_strategy)?(c=await Ye(t,e),l=s&&await Ye(t,s)||""):Ve(a.prefix_strategy)&&(c=await Qe(t,e),l=s&&await Qe(t,s)||""),c&&(r[o]=c,i[o]=l)}var a;return{folderPaths:r,parentPaths:i}}async function Os(e,t,n){const r=await n("directus_folders").select("id","name","parent").where("id",e).first();if(!r)return null;const i=String(r.name);if(i===t)return null;const o=r.parent?String(r.parent):null,s=new Set([e,...await Re(n,o,i),...await Re(n,o,t)]),a={};for(const e of s){const t=await Ye(n,e);t&&(a[e]=t)}return a}async function Ps(e,t){const n=await t("directus_folders").select("id","name","parent").where("id",e).first();if(!n)return null;const r=String(n.name),i=n.parent?String(n.parent):null,o=(await Re(t,i,r)).filter(t=>t!==e),s={};for(const e of o){const n=await Ye(t,e);n&&(s[e]=n)}return{parent:i,name:r,siblingOldPaths:s}}async function Ns(e,t,n,r,i){const o=As(r);if(o.length)for(const[e,r]of Object.entries(t)){const t=await Ye(n,e);t&&r&&t!==r&&await Es(n,o,r,t,i)}}async function Ts(e,t,n,r){const i=As(n);if(i.length)for(const[n,o]of Object.entries(e)){const e=await Ye(t,n);e&&o&&e!==o&&await Es(t,i,o,e,r)}}async function Zs(e,t,n,r,i,o){for(const[e,s]of Object.entries(t)){const t=i[e];if(!t||!Ke(t))continue;const a=n[e]??"";await Es(r,[e],s,a,o)}}async function Cs(e){const t=await e.database("directus_files").select("id","storage","filename_disk","folder","type","uploaded_on").where("id",e.fileId).first();if(!t?.filename_disk)return;const n=String(t.storage??(r=e.env,String(r.STORAGE_LOCATIONS??"local").split(",").map(e=>e.trim()).filter(Boolean)[0]??"local"));var r;const i=Ce(await Te(e.database),n);if(!Ke(i))return;const o=await tt(i,t,e.database);if(!o)return;const s=String(t.filename_disk);if(s.startsWith(`${o}/`)||s===o)return;const a=(await ne(e.database,n,[e.fileId],o,e.logger,e.env)).results[0];"failed"===a?.status&&e.logger.warn(`[storage-manager] Upload mirror failed for ${e.fileId}: ${a.error||"unknown error"}`)}const Fs=new Set(["storage-manager-file-with-storage","storage-manager-image-with-storage","storage-manager-files-with-storage","file","file-image","files"]);async function Ds(e){const t=await e("directus_fields").select("collection","field","interface","options"),n=new Map;for(const e of t||[]){const t=String(e.interface||"");if(!Fs.has(t))continue;let r={};try{r="string"==typeof e.options?JSON.parse(e.options):e.options&&"object"==typeof e.options?e.options:{}}catch{r={}}const i=r.onDeselect,o=r.onItemDelete;n.set(`${e.collection}.${e.field}`,{onDeselect:"keep"===i||"ask"===i||"delete_if_unreferenced"===i?i:null,onItemDelete:"keep"===o||"delete_if_unreferenced"===o?o:null})}return n}function Bs(e){if(null==e)return[];if("string"==typeof e||"number"==typeof e){const t=wt(String(e));return t?[t]:[]}if(Array.isArray(e)){const t=[];for(const n of e)t.push(...Bs(n));return t}if("object"==typeof e){const t=e;if(null!=t.id)return Bs(t.id);if(null!=t.directus_files_id)return Bs(t.directus_files_id);for(const e of Object.values(t))if(e&&"object"==typeof e){const t=Bs(e);if(t.length)return t}}return[]}const Us=[{name:"storage-manager-hook",config:({filter:e,action:t},{database:n,env:r,services:i,getSchema:o,logger:s})=>{t("server.start",async()=>{await Fe(n,i,o,s)}),function({filter:e,action:t},n){const{database:r,services:i,getSchema:o,logger:s}=n,a=new Map,c=new Map;function l(e,t){return`${e}::${[...t].map(String).sort().join(",")}`}e("items.delete",async(e,t)=>{try{const n=String(t?.collection||"");if(!n||"directus_files"===n)return e;const i=Oe((await Te(r)).lifecycle??Ie),c=await Ds(r),u=await o(),d=Array.isArray(u?.relations)?u.relations:[],f=It(u),p=f.filter(e=>e.collection===n),g=[];for(const e of f){if(e.collection===n)continue;const t=d.find(t=>String(t?.collection)===e.collection&&String(t?.related_collection)===n&&String(t?.field)!==e.field);t?.field&&g.push({table:e.collection,fileField:e.field,parentField:String(t.field)})}if(!p.length&&!g.length)return e;const m=(Array.isArray(e)?e:[e]).map(String).filter(Boolean);if(!m.length)return e;const h=u.collections?.[n]?.primary||"id",_=new Set;if(p.length){const e=await r(n).select("*").whereIn(h,m);for(const t of e)for(const e of p){const r=c.get(`${n}.${e.field}`);if("delete_if_unreferenced"===(r?.onItemDelete??i.on_item_delete))for(const n of Bs(t[e.field]))_.add(n)}}if("delete_if_unreferenced"===i.on_item_delete)for(const e of g)try{const t=await r(e.table).select(e.fileField).whereIn(e.parentField,m).whereNotNull(e.fileField);for(const n of t)for(const t of Bs(n[e.fileField]))_.add(t)}catch(t){s.warn(`[storage-manager] lifecycle junction capture ${e.table}: ${t?.message||t}`)}_.size&&a.set(l(n,m),Array.from(_))}catch(e){s.warn(`[storage-manager] lifecycle items.delete capture failed: ${e?.message||e}`)}return e}),t("items.delete",async e=>{try{const t=l(String(e?.collection||""),(e.keys??e.payload??(e.key?[e.key]:[])).map(String)),n=a.get(t);if(a.delete(t),!n?.length)return;const c=Oe((await Te(r)).lifecycle??Ie),u=await o();await Dt(r,u,i,null,n,{scanTextFields:c.scan_text_fields,logger:s})}catch(e){s.warn(`[storage-manager] lifecycle items.delete cleanup failed: ${e?.message||e}`)}}),e("items.update",async(e,t)=>{try{const n=String(t?.collection||"");if(!n||"directus_files"===n)return e;if(!e||"object"!=typeof e)return e;const i=Oe((await Te(r)).lifecycle??Ie),s=await Ds(r),a=await o(),u=It(a).filter(e=>e.collection===n);if(!u.length)return e;const d=u.filter(t=>Object.prototype.hasOwnProperty.call(e,t.field));if(!d.length)return e;const f=(t.keys??[]).map(String).filter(Boolean);if(!f.length)return e;const p=a.collections?.[n]?.primary||"id",g=await r(n).select([p,...d.map(e=>e.field)]).whereIn(p,f),m=new Set;for(const t of g)for(const r of d){const o=s.get(`${n}.${r.field}`);if("delete_if_unreferenced"!==(o?.onDeselect??i.on_deselect))continue;const a=e[r.field],c=Bs(t[r.field]),l=new Set(Bs(a));for(const e of c)l.has(e)||m.add(e)}m.size&&c.set(l(n,f),Array.from(m))}catch(e){s.warn(`[storage-manager] lifecycle items.update capture failed: ${e?.message||e}`)}return e}),t("items.update",async e=>{try{const t=l(String(e?.collection||""),(e.keys??(e.key?[e.key]:[])).map(String)),n=c.get(t);if(c.delete(t),!n?.length)return;const a=Oe((await Te(r)).lifecycle??Ie),u=await o();await Dt(r,u,i,null,n,{scanTextFields:a.scan_text_fields,logger:s})}catch(e){s.warn(`[storage-manager] lifecycle items.update cleanup failed: ${e?.message||e}`)}})}({filter:e,action:t},{database:n,services:i,getSchema:o,logger:s}),e("settings.update",e=>(C in e&&Ne(),e)),e("files.create",async e=>{try{const t=String(r.STORAGE_LOCATIONS??"local").split(",").map(e=>e.trim()).filter(Boolean),i=String(e.storage??t[0]??"local"),o=Ce(await Te(n),i);if(!Ke(o))return e;const s=await tt(o,e,n);if(!s)return e;const a=String(e.filename_disk??"");a.startsWith(`${s}/`)||(e.filename_disk=`${s}/${a}`)}catch(e){s.warn(`[storage-manager] Prefix injection failed: ${e?.message}`)}return e}),t("files.upload",async e=>{if(null!=e.key)try{await Cs({database:n,env:r,fileId:String(e.key),logger:s})}catch(e){s.warn(`[storage-manager] Upload mirror failed: ${e?.message}`)}}),t("folders.create",async e=>{try{const t=e.keys??(e.key?[e.key]:[]);for(const e of t)await Le(e,n,s)}catch(e){s.warn(`[storage-manager] Folder create claim update failed: ${e?.message}`)}});const a=new Map,c=new Map;e("folders.update",async(e,t)=>{if(!e.name)return e;try{const r=await Te(n),i=Object.values(r.locations).some(e=>Ke(e)&&He(e.prefix_strategy)),o=t.keys??(t.key?[t.key]:[]),s=String(e.name);for(const e of o){const t=await n("directus_folders").select("name","parent").where("id",e).first();if(t&&c.set(e,{oldName:String(t.name),newName:s,parent:t.parent?String(t.parent):null}),!i)continue;const r=await Os(e,s,n);r&&Object.keys(r).length&&a.set(e,r)}}catch(e){s.warn(`[storage-manager] Folder rename pre-capture failed: ${e?.message}`)}return e}),t("folders.update",async e=>{if(e.payload?.name)try{const t=await Te(n),r=e.keys??(e.key?[e.key]:[]);for(const e of r){const r=c.get(e);c.delete(e),r&&await We(e,r.oldName,r.newName,r.parent,n,s);const i=a.get(e);a.delete(e),i&&await Ns(0,i,n,t.locations,s)}}catch(e){s.error(`[storage-manager] Folder rename sync error: ${e?.message}`)}});const l=new Map,u=new Map,d=new Map;e("folders.delete",async e=>{try{const t=await Te(n),r=Object.values(t.locations).some(e=>Ke(e)),i=Object.values(t.locations).some(e=>Ke(e)&&He(e.prefix_strategy));for(const o of e){const e=await Ge(o,n);if(e&&d.set(o,e),!r)continue;const s=await Is(o,n,t.locations);if(Object.keys(s.folderPaths).length&&l.set(o,s),i){const e=await Ps(o,n);e&&Object.keys(e.siblingOldPaths).length&&u.set(o,e.siblingOldPaths)}}}catch(e){s.warn(`[storage-manager] Folder delete pre-capture failed: ${e?.message}`)}return e}),t("folders.delete",async e=>{const t=e.keys??[];try{const e=await Te(n);for(const r of t){const t=d.get(r);d.delete(r),t&&await Je(r,t.parent,t.name,n,s);const i=l.get(r);l.delete(r),i&&await Zs(0,i.folderPaths,i.parentPaths,n,e.locations,s);const o=u.get(r);u.delete(r),o&&await Ts(o,n,e.locations,s)}}catch(e){s.error(`[storage-manager] Folder delete sync error: ${e?.message}`)}});const f=new Map;e("files.delete",async e=>{try{const t=await async function(e,t){const n=(t||[]).map(String).filter(Boolean);if(!n.length)return[];const r=await e("directus_files").select("id","storage","filename_disk").whereIn("id",n),i=[];for(const e of r||[]){const t=String(e?.filename_disk||"").replace(/\\/g,"/").replace(/^\/+/,"");if(!t.includes("/"))continue;const n=String(e?.storage||"").trim();n&&i.push({id:String(e.id),storage:n,filename_disk:t})}return i}(n,e);for(const e of t)f.set(e.id,e)}catch(e){s.warn(`[storage-manager] Nested file delete pre-capture failed: ${e?.message}`)}return e}),t("files.delete",async e=>{const t=(e.keys??[]).map(String),n=[];for(const e of t){const t=f.get(e);t&&(f.delete(e),n.push(t))}if(n.length)try{await async function(e,t){if(!e.length)return;const n=await g();for(const r of e)try{const e=n.location(r.storage);await j(e,r.filename_disk)}catch(e){t?.warn(`[storage-manager] Nested file leftover after delete (${r.storage}/${r.filename_disk}): ${e?.message||e}`)}}(n,s)}catch(e){s.warn(`[storage-manager] Nested file leftover cleanup failed: ${e?.message}`)}})}}],Rs=[{name:"storage-manager-endpoint",config:Vt}],Ms=[{name:"storage-manager-operation",config:Kt}];export{Rs as endpoints,Us as hooks,Ms as operations};
|
|
1
|
+
import{Readable as e,Transform as t}from"node:stream";import n from"node:path";import{createRequire as r}from"node:module";import i from"node:fs";import{pathToFileURL as o,fileURLToPath as s}from"node:url";import a from"node:fs/promises";import{randomUUID as c}from"node:crypto";function l(e){return!(!e||"object"!=typeof e)&&!0===e.admin}let u=null;async function d(e){try{const t=await(import(e)),n=t?.getStorage||t?.default?.getStorage;if("function"==typeof n)return n}catch{}return null}async function f(e){if(!i.existsSync(e))return null;try{const t=r(n.join(process.cwd(),"package.json"))(e),i=t?.getStorage||t?.default?.getStorage;if("function"==typeof i)return i}catch{}try{return await d(o(e).href)}catch{return null}}async function p(){if(u)return u;const e=["@directus/api/dist/storage/index.js","@directus/api/storage/index.js","directus/dist/storage/index.js"];for(const t of e){const e=await d(t);if(e)return u=e,e}for(const e of function(){const e=process.cwd(),t=Array.from(new Set([e,n.resolve(e,".."),"/directus",n.dirname(process.execPath)].filter(Boolean))),r=["node_modules/@directus/api/dist/storage/index.js","node_modules/@directus/api/storage/index.js","node_modules/directus/dist/storage/index.js","node_modules/directus/storage/index.js"],i=[];for(const e of t)for(const t of r)i.push(n.join(e,t));return i}()){const t=await f(e);if(t)return u=t,t}throw new Error("Could not resolve Directus getStorage(). Ensure this extension runs inside the Directus API process (not sandboxed).")}async function g(){return(await p())()}async function m(e,t){if("function"==typeof e.read)return await e.read(t);if("function"==typeof e.getStream)return e.getStream(t);throw new Error("Storage disk does not support read/getStream")}async function h(e,t,n,r){if("function"!=typeof e.write){if("function"!=typeof e.put)throw new Error("Storage disk does not support write/put");await e.put(t,n,r||void 0)}else await e.write(t,n,r||void 0)}async function _(e,t){if("function"==typeof e.exists)return await e.exists(t);try{return await y(e,t),!0}catch{return!1}}async function y(e,t){if("function"==typeof e.stat){const n=await e.stat(t);return{size:Number(n.size)||0}}if("function"==typeof e.getStat){const n=await e.getStat(t);return{size:Number(n.size)||0}}throw new Error("Storage disk does not support stat/getStat")}async function w(e,t){if("function"!=typeof e.delete)throw new Error("Storage disk does not support delete");await e.delete(t)}async function*v(e,t=""){if("function"!=typeof e.list)throw new Error("Storage disk does not support list() — cannot detect orphan files on this driver");for await(const n of e.list(t))yield String(n)}const k=/__[a-f0-9]{16,}(?:\.[^.]+)?$/i;function S(e){const t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,""),r=n.posix.parse(t);return{dir:r.dir,stem:r.name}}function b(e,t){return e.startsWith(`${t}__`)&&k.test(e)}async function $(e,t){if("function"!=typeof e.list)return[];const{dir:r,stem:i}=S(t);if(!r)return[];const o=[];for await(const t of e.list(`${r}/${i}`)){const e=String(t||"").replace(/^[/\\]+/,""),s=n.posix.basename(e);n.posix.dirname(e)===r&&b(s,i)&&o.push(e)}return o}async function z(e,t){const n=await async function(e,t){if("function"!=typeof e.list)return[];const{stem:n}=S(t),r=[];for await(const t of e.list(n)){const e=String(t||"").replace(/^[/\\]+/,"");e.includes("/")||b(e,n)&&r.push(e)}return r}(e,t),r=await $(e,t);return[...new Set([...n,...r])]}async function j(e,t){const n=await z(e,t);for(const t of n)try{await w(e,t)}catch{}try{await w(e,t)}catch{}}const x={local:{id:"local",label:"Local Disk",short:"Local",icon:"hard_drive"},s3:{id:"s3",label:"Amazon S3",short:"S3",icon:"cloud"},gcs:{id:"gcs",label:"Google Cloud Storage",short:"GCS",icon:"cloud_queue"},azure:{id:"azure",label:"Azure Blob",short:"Azure",icon:"cloud_done"},cloudinary:{id:"cloudinary",label:"Cloudinary",short:"Cloudinary",icon:"photo_library"},supabase:{id:"supabase",label:"Supabase",short:"Supabase",icon:"storage"}};function A(e,t){const n=e[t];if(null==n)return null;const r=String(n).trim();return""===r?null:r}function E(e){const t=(n=e.STORAGE_LOCATIONS)?Array.isArray(n)?n.map(e=>String(e).trim()).filter(Boolean):String(n).split(",").map(e=>e.trim()).filter(Boolean):[];var n;return t.length>0?t:["local"]}function I(e,t){return A(e,`STORAGE_${t.toUpperCase()}_DRIVER`)||"local"}function O(e,t){return A(e,`STORAGE_${t.toUpperCase()}_ROOT`)}function P(e,t){return A(e,`STORAGE_${t.toUpperCase()}_BUCKET`)||A(e,`STORAGE_${t.toUpperCase()}_CONTAINER_NAME`)}async function N(e,t){const n=new Map;for(const e of t)n.set(e,{file_count:0,total_bytes:0});if(!t.length)return n;const r=await e("directus_files").whereIn("storage",t).select("storage").select(e.raw("count(*) as file_count"),e.raw("coalesce(sum(filesize), 0) as total_bytes")).groupBy("storage");for(const e of r||[])n.set(String(e.storage),{file_count:Number(e.file_count||0),total_bytes:Number(e.total_bytes||0)});return n}async function T(e,t,r,o){const s=I(e,r),{file_count:a,total_bytes:c}=o||await async function(e,t){return(await N(e,[t])).get(t)||{file_count:0,total_bytes:0}}(t,r);let l={disk_total_bytes:null,disk_free_bytes:null,disk_used_bytes:null,disk_used_percent:null,disk_available:!1};return"local"===s&&(l=await async function(e){const t={disk_total_bytes:null,disk_free_bytes:null,disk_used_bytes:null,disk_used_percent:null,disk_available:!1};if(!e)return t;const r=process.env.PWD||process.cwd()||"/directus",o=n.isAbsolute(e)?e:n.join(r,e);try{if(!i.existsSync(o))return t;const e=i.promises.statfs;if("function"==typeof e){const t=await e(o),n=Number(t.bsize||t.frsize||0),r=n*Number(t.blocks||0),i=n*Number(t.bavail??t.bfree??0),s=Math.max(0,r-i);return{disk_total_bytes:r||null,disk_free_bytes:i||null,disk_used_bytes:s||null,disk_used_percent:r>0?s/r*100:null,disk_available:r>0}}}catch{}return t}(O(e,r))),{location:r,driver:s,file_count:a,total_bytes:c,...l}}async function Z(e,t,n,r){const i=await T(e,t,n,r),o=function(e){const t=String(e||"local").toLowerCase();return x[t]||{id:t,label:t,short:t.slice(0,8).toUpperCase(),icon:"storage"}}(i.driver);return{...i,label:o.label,short:o.short,icon:o.icon,root:O(e,n),bucket:P(e,n),folder_count:0,mirror_directus_folders:!1}}const C="storage_manager",F=".keep",D={prefix_strategy:"none",folder_sync_enabled:!1,folder_sync_rename:"full_sync",folder_sync_delete:"move_to_parent",type_map:{image:"images",video:"videos",audio:"audio",text:"documents"},date_format:"yyyy/MM"};function B(e){return String(e||"").replace(/\\/g,"/").replace(/^\/+|\/+$/g,"").replace(/\/+/g,"/")}function U(...e){return e.map(e=>B(e)).filter(Boolean).join("/")}function R(e,t,r,i=!1){const o=B(t),s=B(e);if(i)return s?o?`${o}/${s}`:s:o;const a=(r||[]).map(e=>B(e)).filter(Boolean).sort((e,t)=>t.length-e.length);for(const e of a)if(s===e||s.startsWith(`${e}/`)){const t=n.posix.basename(e),r=s===e?"":s.slice(e.length+1),i=r?`${t}/${r}`:t;return o?`${o}/${i}`:i}const c=n.posix.basename(s);return o?`${o}/${c}`:c}function M(e){return n.basename(e)===F}function q(e,t){const r=process.env.PWD||process.cwd()||"/directus",i=n.isAbsolute(e)?e:n.join(r,e),o=n.resolve(i,t);if(!o.startsWith(n.resolve(i)))throw new Error("Invalid storage path");return o}function L(e){const t=String(e||"").trim();if(!t)throw new Error("Folder name is required");if(t.includes("/")||t.includes("\\"))throw new Error("Folder name cannot contain slashes");if("."===t||".."===t||t===F)throw new Error("Invalid folder name");return t}async function W(e,t,n){const r=new Set,i=I(n,e),o=O(n,e),s=B(t);if("local"===i&&o){const e=q(o,s||".");try{const t=await a.readdir(e,{withFileTypes:!0});for(const e of t)e.isDirectory()&&e.name&&!e.name.startsWith(".")&&r.add(e.name)}catch{}return r}try{const t=(await g()).location(e),n=s?`${s}/`:"";for await(const e of v(t,n)){const t=String(e||"").replace(/^[/\\]+/,"");if(!t.startsWith(n)&&n)continue;const i=n?t.slice(n.length):t,o=i.split("/")[0];o&&!o.startsWith(".")&&(i.includes("/")?r.add(o):M(t))}}catch{}return r}async function J(e,t,n){const r=B(n),i=r?`${r}/`:"",o=String(e?.client?.config?.client||e?.client?.driverName||e?.client?.dialect||"").toLowerCase(),s=i.length+1;try{let n=[];const r=e("directus_files").where("storage",t).whereNotNull("filename_disk");if(i?r.where("filename_disk","like",`${i}%`):r.where("filename_disk","like","%/%"),o.includes("pg")||o.includes("cockroach")){const t=i?`substring(filename_disk from ${s})`:"filename_disk";n=await r.whereRaw(`${t} like ?`,["%/%"]).select(e.raw(`DISTINCT split_part(${t}, '/', 1) as segment`))}else if(o.includes("mysql")||o.includes("maria")){const t=i?`SUBSTRING(filename_disk, ${s})`:"filename_disk";n=await r.whereRaw(`${t} like ?`,["%/%"]).select(e.raw(`DISTINCT SUBSTRING_INDEX(${t}, '/', 1) as segment`))}else if(o.includes("sqlite")){const t=i?`substr(filename_disk, ${s})`:"filename_disk";n=await r.whereRaw(`instr(${t}, '/') > 0`).select(e.raw(`DISTINCT substr(${t}, 1, instr(${t}, '/') - 1) as segment`))}else{if(!o.includes("mssql"))return new Set;{const t=i?`SUBSTRING(filename_disk, ${s}, 4000)`:"filename_disk";n=await r.whereRaw(`CHARINDEX('/', ${t}) > 0`).select(e.raw(`DISTINCT LEFT(${t}, CHARINDEX('/', ${t}) - 1) as segment`))}}const a=new Set;for(const e of n){const t=String(e.segment||"").trim();!t||t.startsWith(".")||t.includes("/")||t.includes("\\")||a.add(t)}return a}catch{return new Set}}async function G(e,t,r){const i=new Set;if("local"===I(r,e))return i;const o=B(t),s=o?`${o}/`:"";try{const t=(await g()).location(e);for await(const e of v(t,s)){const t=String(e||"").replace(/^[/\\]+/,"");if(!M(t))continue;const r=B(n.posix.dirname(t));if(o){if(r===o)continue;if(!r.startsWith(`${o}/`))continue;const e=r.slice(o.length+1).split("/")[0];e&&!e.startsWith(".")&&i.add(e)}else{const e=r.split("/").filter(Boolean);1===e.length&&i.add(e[0])}}}catch{}return i}async function H(e,t,n,r){const i=B(n),o=new Set;for(const n of await J(e,t,i))o.add(n);for(const e of await W(t,i,r))o.add(e);for(const e of await G(t,i,r))o.add(e);const s=Array.from(o).sort((e,t)=>e.localeCompare(t)).map(e=>({name:e,path:U(i,e)}));return{path:i,folders:s}}function V(e,t){const n=B(t).split("/").filter(Boolean);for(let t=1;t<=n.length;t++)e.add(n.slice(0,t).join("/"))}async function K(e,t,r){const i=new Set;for(const r of await async function(e,t){const r=new Set,i=await e("directus_files").select("filename_disk").where("storage",t);for(const e of i){const t=String(e.filename_disk||"").replace(/^[/\\]+/,"");if(!t||M(t))continue;const i=B(n.posix.dirname(t));i&&"."!==i&&V(r,i)}return r}(e,t))i.add(r);for(const e of await async function(e,t){const n=new Set,r=I(t,e),i=O(t,e);return"local"===r&&i?(await async function e(t){const r=q(i,t||".");let o;try{o=await a.readdir(r,{withFileTypes:!0})}catch{return}for(const r of o){if(!r.isDirectory()||!r.name||r.name.startsWith("."))continue;const i=U(t,r.name);n.add(i),await e(i)}}(""),n):n}(t,r))i.add(e);for(const e of await async function(e,t){const r=new Set;if("local"===I(t,e))return r;try{const t=(await g()).location(e);for await(const e of v(t,"")){const t=String(e||"").replace(/^[/\\]+/,"");if(!M(t))continue;const i=B(n.posix.dirname(t));i&&"."!==i&&V(r,i)}}catch{}return r}(t,r))i.add(e);return Array.from(i)}function X(e,t,n){const r=B(e);if(!r)return"";if(null==t)return r;if(n?.length)return R(`${r}/__folder__`,t,n).replace(/\/__folder__$/,"");const i=B(t);return i?`${i}/${r}`:r}async function Y(e,t,n){const r=B(t);if(!r)return;let i="";for(const t of r.split("/").filter(Boolean))await te(e,t,i,n),i=U(i,t)}async function Q(e,t,n){const r=B(t);if(!r)return;if("local"===I(n,e)){const t=O(n,e);if(!t)return;const i=q(t,r);try{await a.rm(i,{recursive:!0,force:!0})}catch{}return}try{const t=(await g()).location(e),n=`${r}/${F}`;await _(t,n)&&await w(t,n)}catch{}}async function ee(e){let t=await async function(e,t,r){const i=await K(e,t,r),o=new Set,s=await e("directus_files").select("filename_disk").where("storage",t);for(const e of s){const t=String(e.filename_disk||"").replace(/^[/\\]+/,"");if(!t||M(t))continue;const r=B(n.posix.dirname(t));r&&"."!==r&&V(o,r)}return i.filter(e=>!o.has(e))}(e.database,e.sourceLocation,e.env);t=function(e,t,n){if(t?.length){const n=t.map(e=>B(e)).filter(Boolean);return e.filter(e=>n.some(t=>e===t||e.startsWith(`${t}/`)))}if(n){const t=B(n);return t?e.filter(e=>e===t||e.startsWith(`${t}/`)):e}return e}(t,e.sourceFolders,e.sourcePath),t.sort((e,t)=>e.length-t.length);let r=0;for(const n of t){const t=X(n,e.targetPath,e.sourceFolders);if(t)try{await Y(e.targetLocation,t,e.env),r+=1}catch(t){e.logger?.warn(`[storage-manager] Failed copying empty folder ${n}: ${t?.message||t}`)}}if(e.removeSource&&r)for(const n of[...t].sort((e,t)=>t.length-e.length))try{await Q(e.sourceLocation,n,e.env),await ie(e.sourceLocation,`${n}/.keep`,e.env)}catch{}return r}async function te(t,n,r,i){const o=U(r,L(n));if("local"===I(i,t)){const e=O(i,t);if(!e)throw new Error(`Local storage “${t}” has no STORAGE_${t.toUpperCase()}_ROOT`);const n=q(e,o);return await a.mkdir(n,{recursive:!0}),{path:o}}const s=(await g()).location(t),c=`${o}/${F}`;if(!await _(s,c)){const t=e.from([Buffer.alloc(0)]);await h(s,c,t,"application/octet-stream")}return{path:o}}async function ne(e,t,n,r,i,o,s,a=!1){const c=(await g()).location(t),l=[],u=await e("directus_files").select("id","storage","filename_disk","type").where("storage",t).whereIn("id",n.map(String));for(const n of u){const u=String(n.id),d=String(n.filename_disk||""),f=R(d,r,s,a);if(d&&d!==f)try{if(!await _(c,d))throw new Error("Source object missing on storage");if(await e("directus_files").select("id").where({storage:t,filename_disk:f}).whereNot({id:u}).first()){l.push({id:u,from:d,to:f,status:"skipped",error:"Destination already has a file at this path — left in place"});continue}if(!await _(c,f)){const e=await m(c,d);if(await h(c,f,e,n.type),!await _(c,f))throw new Error("Write verification failed")}try{const e=await $(c,d);for(const t of e)try{await w(c,t)}catch{}}catch{}await w(c,d),await e("directus_files").where("id",u).update({filename_disk:f}),await ie(t,d,o),l.push({id:u,from:d,to:f,status:"moved"}),i?.info(`[storage-manager] Moved ${d} → ${f} on ${t}`)}catch(e){l.push({id:u,from:d,to:f,status:"failed",error:e?.message||String(e)}),i?.warn(`[storage-manager] Move failed for ${u}: ${e?.message}`)}else l.push({id:u,from:d,to:f,status:"moved"})}return{moved:l.filter(e=>"moved"===e.status).length,failed:l.filter(e=>"failed"===e.status).length,skipped:l.filter(e=>"skipped"===e.status).length,results:l}}function re(e){const t=B(e),n=t.lastIndexOf("/");return-1===n?"":t.slice(0,n)}async function ie(e,t,n){if(!n||"local"!==I(n,e))return;const r=O(n,e);if(!r)return;let i=re(t);for(;i;){const e=q(r,i);try{if((await a.readdir(e)).length>0)return;await a.rmdir(e)}catch{return}i=re(i)}}async function oe(t,r,i,o,s,c){const l=B(i),u=B(o);if(!l)throw new Error("Source folder path is required");if(!u)throw new Error("Destination folder path is required");if(l===u)return{path:u,moved:0,failed:0};if(u.startsWith(`${l}/`))throw new Error("Cannot move a folder into itself");if(L(n.posix.basename(u)),await async function(e,t,r,i){const o=B(r);if(!o)return!1;if(await e("directus_files").select("id").where("storage",t).whereRaw("filename_disk LIKE ?",[`${o}/%`]).first())return!0;const s=re(o),a=n.posix.basename(o),c=new Set;for(const n of await J(e,t,s))c.add(n);for(const e of await W(t,s,i))c.add(e);for(const e of await G(t,s,i))c.add(e);return c.has(a)}(t,r,u,s))throw new Error(`Folder already exists: ${u}`);const{moved:d,failed:f}=await se(t,r,l,u,c);if(f>0)throw new Error(`Failed to relocate ${f} file(s) under ${l}`);if("local"===I(s,r)){const e=O(s,r);if(!e)throw new Error(`Local storage “${r}” has no STORAGE_${r.toUpperCase()}_ROOT`);const t=q(e,l),i=q(e,u);await a.mkdir(n.dirname(i),{recursive:!0});try{await a.access(t);try{await a.access(i);const e=await a.readdir(t,{withFileTypes:!0});for(const r of e){const e=n.join(t,r.name),o=n.join(i,r.name);try{await a.rename(e,o)}catch{}}await a.rm(t,{recursive:!0,force:!0})}catch{await a.rename(t,i)}}catch{await a.mkdir(i,{recursive:!0})}}else{const t=(await g()).location(r),n=`${l}/`;try{for await(const e of v(t,n)){const r=String(e||"").replace(/^[/\\]+/,"");if(!r.startsWith(n))continue;const i=u+r.slice(l.length);try{if(await _(t,i)){await w(t,r);continue}const e=await m(t,r);await h(t,i,e,"application/octet-stream"),await w(t,r)}catch(e){c?.warn(`[storage-manager] Folder leftover move failed ${r}: ${e?.message}`)}}}catch{}const i=`${u}/${F}`;if(!await _(t,i)){const n=e.from([Buffer.alloc(0)]);await h(t,i,n,"application/octet-stream")}const o=`${l}/${F}`;if(await _(t,o))try{await w(t,o)}catch{}}return c?.info(`[storage-manager] Relocated folder ${l} → ${u} on ${r} (${d} file(s))`),{path:u,moved:d,failed:f}}async function se(e,t,n,r,i){const o=B(n),s=B(r);if(!o||o===s)return{moved:0,failed:0};const a=await e("directus_files").select("id","filename_disk","type").where("storage",t).whereRaw("filename_disk LIKE ?",[`${o}/%`]);if(!a.length)return{moved:0,failed:0};const c=(await g()).location(t);let l=0,u=0;for(const n of a){const r=String(n.id),a=String(n.filename_disk||"");if(!a.startsWith(`${o}/`))continue;if(M(a))continue;const d=a.slice(o.length).replace(/^\//,""),f=s?`${s}/${d}`:d;try{if(a===f){l++;continue}if(!await _(c,a)){await e("directus_files").where("id",r).update({filename_disk:f}),l++,i?.warn(`[storage-manager] Prefix relocate DB-only (missing source): ${a} → ${f}`);continue}if(await _(c,f))throw new Error(`Target already exists: ${f}`);const o=await m(c,a);if(await h(c,f,o,n.type),!await _(c,f))throw new Error("Write verification failed");try{const e=await $(c,a);for(const t of e)try{await w(c,t)}catch{}}catch{}await w(c,a),await e("directus_files").where("id",r).update({filename_disk:f}),l++,i?.info(`[storage-manager] Prefix relocate ${a} → ${f} on ${t}`)}catch(e){u++,i?.warn(`[storage-manager] Prefix relocate failed for ${r}: ${e?.message}`)}}return{moved:l,failed:u}}function ae(e){return String(e.title||e.filename_download||e.filename_disk||e.id)}async function ce(e,t,n,r){await j(e,t.filename_disk);try{await ie(t.storage,t.filename_disk,n)}catch(e){r?.warn?.(`[storage-manager] Failed pruning empty folders after ${t.filename_disk}: ${e instanceof Error?e.message:String(e)}`)}}async function le(e,t,n,r){const i=new Array(e.length);let o=0;const s=Array.from({length:Math.min(t,e.length)||1},()=>async function(){for(;o<e.length;){if(r?.())return;const t=o++;i[t]=await n(e[t],t)}}());return await Promise.all(s),i}async function ue(e,t,r,i){let o;try{o=await z(e,r)}catch(e){return void i?.warn?.(`[storage-manager] Could not list asset transforms for ${r}: ${e instanceof Error?e.message:String(e)}`)}for(const r of o)try{const i=n.posix.basename(r);if(await _(t,i))continue;const o=await m(e,r);await h(t,i,o,null)}catch(e){i?.warn?.(`[storage-manager] Failed copying asset transform ${r}: ${e instanceof Error?e.message:String(e)}`)}}async function de(e,n,r,i,o,s,a,c=!1,l){const u={id:e.id,filename_disk:a||e.filename_disk,from:e.storage,to:n,status:"failed"};if(!e.filename_disk)return{...u,status:"failed",error:"Missing filename_disk"};const d=String(a||e.filename_disk||"");if(e.storage===n&&d===e.filename_disk)return{...u,status:"skipped",error:"Already on target storage"};const f=await g(),p=f.location(e.storage),w=f.location(n);if(!await _(p,e.filename_disk))return{...u,status:"failed",error:`Source object missing on ${e.storage}`};if(await i("directus_files").select("id").where({storage:n,filename_disk:d}).whereNot({id:e.id}).first())return{...u,status:"skipped",error:"Destination already has a file at this path — left in place"};if(await _(w,d)){if(await ue(p,w,e.filename_disk,o),await i("directus_files").where({id:e.id}).update({storage:n,filename_disk:d}),"move"===r&&!c)try{await ce(p,e,l,o)}catch(t){o?.warn?.(`[storage-manager] DB updated but failed deleting source ${e.id}: ${t instanceof Error?t.message:String(t)}`)}const t=await y(w,d).catch(()=>({size:Number(e.filesize)||0}));return s&&t.size>0&&s(t.size),{...u,status:"move"===r?"moved":"copied",bytes:t.size}}const v=await m(p,e.filename_disk),k=s?v.pipe((S=s,new t({transform(e,t,n){const r=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e);r>0&&S(r),n(null,e)}}))):v;var S;try{await h(w,d,k,e.type)}catch(e){try{await _(w,d)&&await j(w,d)}catch{}return{...u,status:"failed",error:`Write failed: ${e instanceof Error?e.message:String(e)}`}}if(!await _(w,d))return{...u,status:"failed",error:"Target write did not persist (exists check failed)"};let b=0;try{b=(await y(w,d)).size}catch(e){return{...u,status:"failed",error:`Target stat failed after write: ${e instanceof Error?e.message:String(e)}`}}if(null!=e.filesize&&Number(e.filesize)>0&&b>0){const t=Number(e.filesize);if(Math.abs(t-b)>Math.max(64,.01*t)&&b<.95*t){try{await j(w,d)}catch{}return{...u,status:"failed",error:`Size mismatch after write (expected ~${t}, got ${b})`}}}await ue(p,w,e.filename_disk,o);try{await i("directus_files").where({id:e.id}).update({storage:n,filename_disk:d})}catch(e){try{await j(w,d)}catch{}return{...u,status:"failed",error:`DB update failed: ${e instanceof Error?e.message:String(e)}`}}if("move"===r&&!c)try{await ce(p,e,l,o)}catch(t){return o?.warn?.(`[storage-manager] Moved ${e.id} to ${n} but source delete failed: ${t instanceof Error?t.message:String(t)}`),{...u,status:"moved",bytes:b,error:`Moved, but source cleanup failed: ${t instanceof Error?t.message:String(t)}`}}return{...u,status:"move"===r?"moved":"copied",bytes:b}}async function fe(e){const{fileIds:t,targetStorage:n,mode:r,database:i,logger:o,onProgress:s,isCancelled:a,keepSourceFileOnDisk:c,targetPath:l,sourceFolders:u,preservePaths:d,includeEmptyFolders:f,sourceStorage:p,sourcePath:g,env:m}=e,h=Math.min(8,Math.max(1,Number(e.concurrency)||3)),_=Date.now(),y=Array.from(new Set(t.filter(Boolean)));async function w(e){if(!f||!m||a?.())return;const t=p||e||null;if(t&&t!==n)try{await ee({database:i,sourceLocation:t,targetLocation:n,env:m,targetPath:l,sourceFolders:u,sourcePath:g,removeSource:"move"===r&&!c,logger:o})}catch(e){o?.warn?.(`[storage-manager] Empty folder copy failed: ${e instanceof Error?e.message:String(e)}`)}}if(0===y.length){await w(null);const e={mode:r,target_storage:n,total:0,succeeded:0,skipped:0,failed:0,results:[],transferred_bytes:0,total_bytes:0,elapsed_ms:0};return s?.({type:"done",data:e}),e}const v=await i("directus_files").select("id","storage","filename_disk","filename_download","title","type","filesize").whereIn("id",y),k=new Map(v.map(e=>[String(e.id),e])),S=v.reduce((e,t)=>e+(Number(t.filesize)||0),0),b=v.length&&v.every(e=>e.storage===v[0].storage)?v[0].storage:null;s?.({type:"start",mode:r,from:b,to:n,total:y.length,total_bytes:S});let $=0,z=0,j=0,x=0,A=0;const E=new Map;let I=0;const O=await le(y,h,async e=>{if(a?.())return{id:e,filename_disk:"",from:"",to:n,status:"failed",error:"Cancelled"};const t=k.get(e),f=++A;if(!t){x+=1;const t={id:e,filename_disk:"",from:"",to:n,status:"failed",error:"File not found"};return s?.({type:"file_done",index:f,total:y.length,result:t,name:e,succeeded:z,skipped:j,failed:x,transferred_bytes:$,total_bytes:S,elapsed_ms:Date.now()-_}),t}let p;s?.({type:"file_start",index:f,total:y.length,id:t.id,name:ae(t),filename_disk:t.filename_disk,from:t.storage,to:n,bytes:Number(t.filesize)||0}),E.set(t.id,0);try{p=await de(t,n,r,i,o,e=>((e,t,n)=>{$+=n;const r=(E.get(t.id)||0)+n;E.set(t.id,r);const i=Date.now();i-I<120||(I=i,s?.({type:"file_bytes",index:e,id:t.id,file_transferred:r,file_bytes:Number(t.filesize)||0,transferred_bytes:$,total_bytes:S,elapsed_ms:i-_}))})(f,t,e),null!=l?function(e,t,n,r=!1){return R(e,t,n,r)}(t.filename_disk,l,u,d):void 0,Boolean(c),m)}catch(e){p={id:t.id,filename_disk:t.filename_disk,from:t.storage,to:n,status:"failed",error:e instanceof Error?e.message:String(e)}}if("moved"===p.status||"copied"===p.status){z+=1;const e=E.get(t.id)||0,n=Number(p.bytes)||Number(t.filesize)||0;n>e&&($+=n-e,E.set(t.id,n))}else"skipped"===p.status?j+=1:x+=1;return s?.({type:"file_done",index:f,total:y.length,result:p,name:ae(t),succeeded:z,skipped:j,failed:x,transferred_bytes:$,total_bytes:S,elapsed_ms:Date.now()-_}),p},a);await w(b);const P={mode:r,target_storage:n,total:O.filter(Boolean).length,succeeded:z,skipped:j,failed:x,results:O.filter(Boolean),transferred_bytes:$,total_bytes:S,elapsed_ms:Date.now()-_};return o?.info?.(`[storage-manager] ${r} → ${n}: ${z} ok, ${j} skipped, ${x} failed (of ${P.total})`),s?.({type:"done",data:P}),P}const pe=new Set(["image/jpeg","image/jpg","image/png","image/webp","image/gif","image/tiff","image/tif","image/avif"]);let ge;function me(e){if(!e)return!1;const t=e.toLowerCase();return"image/svg+xml"!==t&&(pe.has(t)||t.startsWith("image/"))}async function he(e){const t=await async function(){if(void 0!==ge)return ge;try{const e=r(n.join(process.cwd(),"package.json"))("sharp"),t="function"==typeof e?e:e?.default;if("function"==typeof t)return ge=t,ge}catch{}try{const e=await(import("sharp")),t="function"==typeof e.default?e.default:e;if("function"==typeof t)return ge=t,ge}catch{}return ge=null,null}();if(!t)return null;try{const n=await t(e,{failOn:"none"}).metadata();let r=n.width??0,i=n.height??0;if(n.orientation&&n.orientation>=5){const e=r;r=i,i=e}if(r>0&&i>0)return{width:r,height:i}}catch{}return null}async function _e(e,t){let n,r;try{n=await m(e,t)}catch{return null}try{r=await async function(e,t){const n=[];let r=0;try{for await(const i of e){const e=Buffer.isBuffer(i)?i:Buffer.from(i);if(n.push(e),r+=e.length,r>=t)break}}finally{!function(e){try{const t=e;"function"==typeof t.destroy&&t.destroy()}catch{}}(e)}const i=Buffer.concat(n);return i.length>t?i.subarray(0,t):i}(n,2097152)}catch{return null}return r.length?await he(r)||function(e){return function(e){if(e.length<24)return null;if(137!==e[0]||"PNG"!==e.toString("ascii",1,4))return null;const t=e.readUInt32BE(16),n=e.readUInt32BE(20);return t>0&&n>0?{width:t,height:n}:null}(e)||function(e){if(e.length<10||255!==e[0]||216!==e[1])return null;let t=2;for(;t+8<e.length;){if(255!==e[t]){t+=1;continue}const n=e[t+1];if(216===n||217===n||n>=208&&n<=215){t+=2;continue}if(1===n){t+=2;continue}if(n>=192&&n<=195||n>=197&&n<=199||n>=201&&n<=203||n>=205&&n<=207){const n=e.readUInt16BE(t+5),r=e.readUInt16BE(t+7);return r>0&&n>0?{width:r,height:n}:null}if(t+4>e.length)return null;const r=e.readUInt16BE(t+2);if(r<2)return null;t+=2+r}return null}(e)||function(e){if(e.length<10)return null;const t=e.toString("ascii",0,6);if("GIF87a"!==t&&"GIF89a"!==t)return null;const n=e.readUInt16LE(6),r=e.readUInt16LE(8);return n>0&&r>0?{width:n,height:r}:null}(e)||function(e){if(e.length<30)return null;if("RIFF"!==e.toString("ascii",0,4)||"WEBP"!==e.toString("ascii",8,12))return null;const t=e.toString("ascii",12,16);if("VP8X"===t){const t=1+e[24]+(e[25]<<8)+(e[26]<<16),n=1+e[27]+(e[28]<<8)+(e[29]<<16);return t>0&&n>0?{width:t,height:n}:null}if("VP8 "===t&&157===e[23]&&1===e[24]&&42===e[25]){const t=16383&e.readUInt16LE(26),n=16383&e.readUInt16LE(28);return t>0&&n>0?{width:t,height:n}:null}if("VP8L"===t&&e.length>=25&&47===e[20]){const t=e.readUInt32LE(21),n=1+(16383&t),r=1+(t>>14&16383);if(n>0&&r>0)return{width:n,height:r}}return null}(e)}(r):null}const ye=/__[a-f0-9]{16,}(?:\.[^.]+)?$/i;function we(e){return ye.test(n.basename(String(e||"")))}function ve(e){const t=String(e||"").replace(/^[/\\]+/,"");return Boolean(t)&&!t.includes("/")}function ke(e){return ve(e)&&we(e)}function Se(e,t){const n=String(t||"").trim().toLowerCase();return!n||String(e||"").toLowerCase().includes(n)}function be(e){const t=n.basename(e);return!(t&&!t.startsWith("."))||("directus-health-file"===t||!!we(e))}const $e={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".avif":"image/avif",".svg":"image/svg+xml",".pdf":"application/pdf",".mp4":"video/mp4",".webm":"video/webm",".mov":"video/quicktime",".mp3":"audio/mpeg",".wav":"audio/wav",".json":"application/json",".txt":"text/plain",".csv":"text/csv",".zip":"application/zip"};function ze(e){const t=n.extname(e).toLowerCase();return $e[t]||null}function je(e){const t=n.parse(n.basename(e)).name;return t.replace(/_/g," ").replace(/\s+/g," ").trim()||t||e}function xe(e){const t=n.parse(n.basename(e)).name;return/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(t)?t.toLowerCase():null}async function Ae(e,t){const r=new Set;if(t){const i=I(t,e),o=O(t,e);if("local"===i&&o){for(const e of await async function(e){const t=n.isAbsolute(e)?e:n.join(process.cwd(),e),r=[];return await async function e(t,i=""){let o;try{o=await a.readdir(t,{withFileTypes:!0})}catch{return}for(const s of o){const o=i?`${i}/${s.name}`:s.name;s.isDirectory()?await e(n.join(t,s.name),o):s.isFile()&&(be(o)||r.push(o))}}(t),r}(o))r.add(e);return Array.from(r)}}const i=(await g()).location(e);try{for await(const e of v(i,"")){const t=String(e||"").replace(/^[/\\]+/,"");t&&!be(t)&&r.add(t)}}catch(t){throw new Error(`Could not list files on storage “${e}”: ${t?.message||t}`)}return Array.from(r)}async function Ee(e,t,r,i){const o=String(i||"").replace(/\\/g,"/").replace(/^\/+|\/+$/g,"").replace(/\/+/g,"/"),s=await Ae(t,r),a=o?s.filter(e=>e===o||e.startsWith(`${o}/`)):s,c=await e("directus_files").select("filename_disk").where("storage",t),l=new Set(c.map(e=>String(e.filename_disk||"")).filter(Boolean)),u=(await g()).location(t),d=[];for(const e of a){if(l.has(e))continue;let t=0;try{const n=await y(u,e);t=Number(n.size)||0}catch{t=0}d.push({filename_disk:e,filesize:t,type:ze(e),suggested_id:xe(e),filename_download:n.basename(e),title:je(e)})}return d.sort((e,t)=>e.filename_disk.localeCompare(t.filename_disk)),{orphans:d,scanned:a.length,known:l.size,path:o}}const Ie={on_deselect:"keep",on_item_delete:"keep",scan_min_age_minutes:60,scan_text_fields:!0};function Oe(e){const t=e&&"object"==typeof e?e:{},n=t.on_deselect,r=t.on_item_delete,i=Number(t.scan_min_age_minutes);return{on_deselect:"ask"===n||"delete_if_unreferenced"===n||"keep"===n?n:Ie.on_deselect,on_item_delete:"delete_if_unreferenced"===r||"keep"===r?r:Ie.on_item_delete,scan_min_age_minutes:Number.isFinite(i)&&i>=0?Math.min(43200,Math.floor(i)):Ie.scan_min_age_minutes,scan_text_fields:void 0===t.scan_text_fields?Ie.scan_text_fields:Boolean(t.scan_text_fields)}}let Pe=null;function Ne(){Pe=null}async function Te(e){if(Pe)return Pe;try{if(!await e.schema.hasColumn("directus_settings",C))return Pe={locations:{}},Pe;const t=await e("directus_settings").select(C).first(),n=t?.[C],r="string"==typeof n?JSON.parse(n):n??{},i={locations:r.locations??{}};return r&&"object"==typeof r&&"name_mirror_claims"in r&&(i.name_mirror_claims=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return{};const t={};for(const[n,r]of Object.entries(e))"string"==typeof n&&n&&"string"==typeof r&&r&&(t[n]=r);return t}(r.name_mirror_claims)),r&&"object"==typeof r&&"lifecycle"in r&&(i.lifecycle=Oe(r.lifecycle)),Pe=i,Pe}catch(e){if(function(e){const t=String(e?.message||e||"");return/does not exist|unknown column|no such column/i.test(t)}(e))return Pe={locations:{}},Pe;throw e}}async function Ze(e,t){await e("directus_settings").update({[C]:JSON.stringify(t)}),Pe=t}function Ce(e,t){return{...D,...e.locations[t]??{}}}async function Fe(e,t,n,r){try{const i=await e.schema.hasColumn("directus_settings",C);if(i)return;const o=await n(),s=new t.FieldsService({database:e,schema:o,accountability:{admin:!0}}),a=await s.readAll("directus_settings"),c=a?.some(e=>e.field===C);if(c&&i)return;await s.createField("directus_settings",{field:C,type:"json",meta:{collection:"directus_settings",field:C,special:["cast-json"],interface:"input-code",hidden:!0,note:"Storage Manager extension settings (do not edit manually)"},schema:null}),Ne(),r.info(`[storage-manager] Created directus_settings.${C}`)}catch(e){r.warn(`[storage-manager] Could not ensure settings field: ${e?.message}`)}}function De(e,t){return`${e??""}::${t}`}function Be(e){const t=new Map;for(const n of e){const e=De(n.parent,n.name),r=t.get(e)??[];r.push(n.id),t.set(e,r)}for(const e of t.values())e.sort((e,t)=>e.localeCompare(t));return t}async function Ue(e){return(await e("directus_folders").select("id","name","parent")).map(e=>({id:String(e.id),name:String(e.name),parent:e.parent?String(e.parent):null}))}async function Re(e,t,n){const r=e("directus_folders").select("id").where("name",n);t?r.where("parent",t):r.whereNull("parent");return(await r).map(e=>String(e.id)).sort((e,t)=>e.localeCompare(t))}async function Me(e,t){const n=await Te(e);if(void 0!==n.name_mirror_claims)return n.name_mirror_claims;const r=function(e){const t={},n=Be(e);for(const[e,r]of n)r[0]&&(t[e]=r[0]);return t}(await Ue(e)),i={...n,name_mirror_claims:r};return await Ze(e,i),t?.info(`[storage-manager] Initialized name_mirror_claims (${Object.keys(r).length} sibling groups)`),r}async function qe(e,t){const n=await Te(e);await Ze(e,{...n,name_mirror_claims:t})}async function Le(e,t,n){const r=await t("directus_folders").select("id","name","parent").where("id",e).first();if(!r)return;const i=String(r.name),o=r.parent?String(r.parent):null,s=De(o,i),a={...await Me(t,n)};0!==(await Re(t,o,i)).filter(t=>t!==e).length?a[s]:a[s]!==e&&(a[s]=e,await qe(t,a))}async function We(e,t,n,r,i,o){if(t===n)return;const s={...await Me(i,o)},a=De(r,t),c=De(r,n);let l=!1;s[a]===e&&(delete s[a],l=!0);0===(await Re(i,r,n)).filter(t=>t!==e).length?s[c]!==e&&(s[c]=e,l=!0):s[c]===e||s[c],l&&await qe(i,s)}async function Je(e,t,n,r,i){const o={...await Me(r,i)},s=De(t,n);o[s]===e&&(delete o[s],await qe(r,o))}async function Ge(e,t){const n=await t("directus_folders").select("name","parent").where("id",e).first();return n?{name:String(n.name),parent:n.parent?String(n.parent):null}:null}function He(e){return"folder"===e}function Ve(e){return"folder_id"===e}function Ke(e){return He(t=e.prefix_strategy)||Ve(t);var t}function Xe(e,t,n,r){return(n.length?n:[t]).length<=1||r===t?e:`${e}_${t}`}async function Ye(e,t){if(!t)return null;return et(await Ue(e),t,"name",await Me(e))}async function Qe(e,t){if(!t)return null;return et(await Ue(e),t,"id")}function et(e,t,n,r={}){if(!t)return null;const i=new Map;for(const t of e)i.set(t.id,t);const o="name"===n?Be(e):null,s=[];let a=String(t),c=0;for(;a&&c<50;){const e=i.get(a);if(!e)break;if("id"===n)s.unshift(a);else{const t=De(e.parent,e.name),n=o.get(t)??[e.id];s.unshift(Xe(e.name,e.id,n,r[t]??null))}a=e.parent,c++}return s.length?s.join("/"):null}async function tt(e,t,n){switch(e.prefix_strategy){case"none":default:return null;case"folder":return await Ye(n,t.folder)||null;case"folder_id":return await Qe(n,t.folder)||null;case"type":{const n=(r=t.type)?r.split("/")[0]??"other":"other";return(e.type_map[n]??e.type_map.other??n)||null}case"date":{const n=e.date_format||"yyyy/MM";return function(e,t){const n=e?new Date(e):new Date;return t.replace("yyyy",String(n.getUTCFullYear())).replace("MM",String(n.getUTCMonth()+1).padStart(2,"0")).replace("dd",String(n.getUTCDate()).padStart(2,"0"))}(t.uploaded_on,n)}}var r}function nt(e){return String(e||"").replace(/\\/g,"/").replace(/\//g,"_").trim()}function rt(e,t){if(!e)return"";const n=[];let r=e,i=0;for(;r&&i<100;){const e=t.get(r);if(!e)break;n.unshift(nt(e.name)),r=e.parent,i+=1}return n.filter(Boolean).join("/")}async function it(e,t){if(!t)return[];const n=await e("directus_folders").select("id","parent"),r=new Map;for(const e of n){const t=null==e.parent?null:String(e.parent),n=String(e.id);r.has(t)||r.set(t,[]),r.get(t).push(n)}const i=[],o=[t];for(;o.length;){const e=o.pop();i.push(e);for(const t of r.get(e)||[])o.push(t)}return i}async function ot(e){const t=await e.database("directus_folders").select("id","name","parent"),r=new Map(t.map(e=>[String(e.id),{...e,id:String(e.id),parent:e.parent?String(e.parent):null}])),i=await it(e.database,e.folderId);let o=e.database("directus_files").select("id","storage","filename_disk","filesize","type","folder").whereNotNull("filename_disk");e.recursive?null!==e.folderId&&(o=o.whereIn("folder",[e.folderId,...i])):o=null===e.folderId?o.whereNull("folder"):o.whereIn("folder",i);const s=await o,a=[];let c=0,l=0,u=0,d=0;const f=Date.now();for(const e of s)d+=Number(e.filesize)||0;let p=0;e.onProgress?.({type:"start",mode:"move",from:"merge"===e.mode?null:"mixed",to:"merge"===e.mode?String(e.targetStorage||""):"preserve",total:s.length,total_bytes:d});for(let t=0;t<s.length;t++){const i=s[t];if(e.isCancelled?.())break;const o="merge"===e.mode?String(e.targetStorage||""):String(i.storage),g=rt(i.folder?String(i.folder):null,r),m=n.posix.basename(String(i.filename_disk||"")),h=g?`${g}/${m}`:m,_=String(i.filename_disk||i.id);if(e.onProgress?.({type:"file_start",index:t+1,total:s.length,id:String(i.id),name:_,filename_disk:String(i.filename_disk||""),from:String(i.storage),to:o,bytes:Number(i.filesize)||0}),e.structureOnly){const n={id:i.id,status:"skipped",filename_disk:h,from:String(i.storage),to:o,error:"Structure-only mode"};a.push(n),u+=1,e.onProgress?.({type:"file_done",index:t+1,total:s.length,result:n,name:_,succeeded:c,skipped:u,failed:l,transferred_bytes:p,total_bytes:d,elapsed_ms:Date.now()-f});continue}try{const n=await de(i,o,"move",e.database,e.logger,void 0,h,Boolean(e.keepSourceFileOnDisk));a.push(n),"failed"===n.status?l+=1:"skipped"===n.status?u+=1:(c+=1,p+=Number(n.bytes)||Number(i.filesize)||0),e.onProgress?.({type:"file_done",index:t+1,total:s.length,result:n,name:_,succeeded:c,skipped:u,failed:l,transferred_bytes:p,total_bytes:d,elapsed_ms:Date.now()-f})}catch(n){const r={id:i.id,status:"failed",filename_disk:h,from:String(i.storage),to:o,error:n?.message||"Materialize failed"};a.push(r),l+=1,e.onProgress?.({type:"file_done",index:t+1,total:s.length,result:r,name:_,succeeded:c,skipped:u,failed:l,transferred_bytes:p,total_bytes:d,elapsed_ms:Date.now()-f})}}const g={mode:"move",target_storage:"merge"===e.mode?String(e.targetStorage||""):"preserve",total:s.length,succeeded:c,failed:l,skipped:u,results:a,transferred_bytes:p,total_bytes:d,elapsed_ms:Date.now()-f};return e.onProgress?.({type:"done",data:g}),g}const st="directus-extension-storage-manager",at=`https://www.npmjs.com/package/${st}`;let ct=null;const lt=18e5;function ut(e){return String(e||"").trim().replace(/^v/,"")}function dt(e){const t=ut(e),[n,r]=t.split("-",2);return{nums:n.split(".").map(e=>parseInt(e,10)).map(e=>Number.isFinite(e)?e:0),prerelease:r?r.split("."):[]}}function ft(e=""){return`${e}/admin/settings/marketplace/extension/88a7639e-db2a-4ade-a97f-94d2cc3836e7`}async function pt(e=!1){if(!e&&ct&&Date.now()<ct.expiresAt)return ct.data;const t=ut(function(){const e=[];try{e.push(n.resolve(n.dirname(s(import.meta.url)),"..","package.json"))}catch{}e.push(n.resolve(process.cwd(),"extensions",st,"package.json"),n.resolve(process.cwd(),"package.json"));for(const t of e)try{const e=JSON.parse(i.readFileSync(t,"utf8"));if(e.name===st&&e.version)return String(e.version)}catch{}return"unknown"}()),r={npm:at,github:"https://github.com/domdus/directus-extension-storage-manager",marketplace:ft("")},o={current_version:t,latest_version:null,has_update:!1,registry:"npm",checked_at:(new Date).toISOString(),release_url:r.npm,links:r};try{const e=await fetch(`https://registry.npmjs.org/${encodeURIComponent(st)}`,{method:"GET",headers:{Accept:"application/json"}});if(!e.ok)throw new Error(`npm registry request failed (${e.status})`);const n=await e.json(),r=ut(n?.["dist-tags"]?.latest||"");if(!r)throw new Error("No latest version found in npm dist-tags");const i=function(e,t){const n=dt(e),r=dt(t),i=Math.max(n.nums.length,r.nums.length,3);for(let e=0;e<i;e++){const t=n.nums[e]??0,i=r.nums[e]??0;if(t>i)return 1;if(t<i)return-1}if(!n.prerelease.length&&r.prerelease.length)return 1;if(n.prerelease.length&&!r.prerelease.length)return-1;const o=Math.max(n.prerelease.length,r.prerelease.length);for(let e=0;e<o;e++){const t=n.prerelease[e],i=r.prerelease[e];if(null==t)return-1;if(null==i)return 1;const o=/^[0-9]+$/.test(t)?parseInt(t,10):null,s=/^[0-9]+$/.test(i)?parseInt(i,10):null;if(null==o||null==s){if(null!=o&&null==s)return-1;if(null==o&&null!=s)return 1;if(t>i)return 1;if(t<i)return-1}else{if(o>s)return 1;if(o<s)return-1}}return 0}(r,t)>0,s={...o,latest_version:r,has_update:i,release_url:i?`${at}?activeTab=versions`:at,checked_at:(new Date).toISOString()};return ct={data:s,expiresAt:Date.now()+lt},s}catch(e){const t={...o,error:e?.message||"Update check failed",checked_at:(new Date).toISOString()};return ct={data:t,expiresAt:Date.now()+Math.min(3e5,lt)},t}}async function*gt(e,t){const r=I(t,e),i=O(t,e);if("local"===r&&i)return void(yield*async function*(e){const t=n.isAbsolute(e)?e:n.join(process.cwd(),e);let r;try{r=await a.readdir(t,{withFileTypes:!0})}catch{return}for(const e of r)e.isFile()&&e.name&&!e.name.startsWith(".")&&"directus-health-file"!==e.name&&(yield e.name)}(i));const o=(await g()).location(e);try{for await(const e of v(o,"")){const t=String(e||"").replace(/^[/\\]+/,"");ve(t)&&(t.startsWith(".")||"directus-health-file"!==t&&(yield t))}}catch{}}async function mt(e,t){try{const n=(await g()).location(e),r=await y(n,t);return{filesize:Number(r.size)||0,type:ze(t)}}catch{return{filesize:0,type:ze(t)}}}async function ht(e){const t=function(e){const t=Number(e);return!Number.isFinite(t)||t<1?1:Math.floor(t)}(e.page),n=function(e,t=50){const n=Number(e);return!Number.isFinite(n)||n<1?t:Math.min(Math.floor(n),200)}(e.limit),r=e.search??null,i=(t-1)*n,o=[];let s=0,a=!1;for await(const t of gt(e.location,e.env))if(ke(t)&&Se(t,r)){if(!(s<i)){if(o.length<n){const n=await mt(e.location,t);o.push({filename_disk:t,filesize:n.filesize,type:n.type});continue}a=!0;break}s++}return{items:o,page:t,limit:n,has_more:a}}const _t=/[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/gi,yt=/(?:^|[^a-z0-9_])(?:\/?assets\/)([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})(?:\b|[/?#])/gi;function wt(e){return String(e||"").trim().toLowerCase()}function vt(e){if(!e)return[];const t=new Set;let n;for(yt.lastIndex=0;null!==(n=yt.exec(e));)n[1]&&t.add(wt(n[1]));return Array.from(t)}function kt(e){if(!e)return[];const t=new Set;let n;for(_t.lastIndex=0;null!==(n=_t.exec(e));)t.add(wt(n[0]));return Array.from(t)}function St(e){if(null==e)return"";if("string"==typeof e)return e;if("number"==typeof e||"boolean"==typeof e)return String(e);try{return JSON.stringify(e)}catch{return String(e)}}const bt=new Set(["directus_activity","directus_revisions","directus_sessions","directus_migrations","directus_notifications","directus_shares","directus_operations","directus_flows","directus_panels","directus_dashboards","directus_versions","directus_extensions","directus_permissions","directus_access","directus_policies","directus_presets","directus_deployments","directus_deployment_projects","directus_deployment_runs","unused_files","unused_files_iteration"]);function $t(e){return!e||(!!bt.has(e)||!!e.startsWith("directus_"))}const zt=new Set(["input-rich-text-html","input-rich-text-md","input-rich-text-mdm","input-code","input-multiline","input-block-editor","json","list","tags","markdown","wysiwyg"]),jt=new Set(["text","json","csv"]);function xt(e){return/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(e)}function At(e,t){const n=e?.collections?.[t]?.primary;return"string"==typeof n&&xt(n)?n:Array.isArray(n)&&1===n.length&&xt(String(n[0]))?String(n[0]):"id"}function Et(){return new Promise(e=>setImmediate(e))}function It(e){const t=Array.isArray(e?.relations)?e.relations:[],n=e?.collections&&"object"==typeof e.collections?e.collections:{},r=[],i=new Set;for(const e of t){if("directus_files"!==String(e?.related_collection||""))continue;const t=String(e.collection||""),o=String(e.field||"");if(!(t&&o&&xt(t)&&xt(o)))continue;if("directus_files"===t)continue;if(bt.has(t))continue;const s=`${t}.${o}`;if(i.has(s))continue;i.add(s);const a=n[t];r.push({collection:t,field:o,singleton:Boolean(a?.singleton)})}return r.sort((e,t)=>e.collection.localeCompare(t.collection)||e.field.localeCompare(t.field))}async function Ot(e,t){const n=await e("directus_fields").select("collection","field","interface","special"),r=t?.collections&&"object"==typeof t.collections?t.collections:{};return(n||[]).map(e=>{const t=String(e.collection||""),n=String(e.field||""),i=r[t]?.fields?.[n]?.type;return{collection:t,field:n,interface:null!=e.interface?String(e.interface):null,type:null!=i?String(i):null,special:null!=e.special?String(e.special):null}})}function Pt(e,t){const n=[],r=new Set;for(const i of e){const{collection:e,field:o}=i;if(!e||!o)continue;if(!xt(e)||!xt(o))continue;if($t(e))continue;if("directus_files"===e)continue;const s=`${e}.${o}`;if(t.has(s))continue;if(r.has(s))continue;const a=(i.special||"").toLowerCase();if(a.includes("alias")||a.includes("no-data"))continue;if(a.includes("file")||a.includes("files"))continue;const c=(i.interface||"").toLowerCase(),l=(i.type||"").toLowerCase(),u=zt.has(c),d=jt.has(l);(u||d)&&(r.add(s),n.push({collection:e,field:o,mode:(!d||"json"!==l&&"csv"!==l&&"input-code"!==c&&"json"!==c&&"list"!==c)&&u&&(c.includes("rich-text")||"wysiwyg"===c||"markdown"===c||"input-rich-text-md"===c||"input-block-editor"===c)?"assets_only":"assets_and_uuids"}))}return n.sort((e,t)=>e.collection.localeCompare(t.collection)||e.field.localeCompare(t.field))}async function Nt(e,t,n){if(n.has(t))return n.get(t);try{const r=Boolean(await e.schema.hasTable(t));return n.set(t,r),r}catch{return n.set(t,!1),!1}}async function Tt(e,t,n,r){const i=`${t}.${n}`;if(r.has(i))return r.get(i);try{const o=Boolean(await e.schema.hasColumn(t,n));return r.set(i,o),o}catch{return r.set(i,!1),!1}}function Zt(e,t){return t.storage&&e.where("storage",String(t.storage)),void 0!==t.folder&&null!==t.folder&&e.where("folder",String(t.folder)),t.cutoff&&e.andWhere(e=>{e.where("uploaded_on","<",t.cutoff).orWhereNull("uploaded_on")}),e}async function Ct(e,t,n={}){const r=Date.now(),i=Math.max(0,Number(n.minAgeMinutes??60)||0),o=!1!==n.scanTextFields,s=Math.min(500,Math.max(1,Number(n.limit??100)||100)),a=Math.max(0,Number(n.offset??0)||0),c=n.onProgress,l=n.isCancelled,u=It(t),d=new Set(u.map(e=>`${e.collection}.${e.field}`));let f=[];if(o){f=Pt(await Ot(e,t),d)}const p=await async function(e,t){const n=new Set,{relations:r,textTargets:i,scanTextFields:o,schema:s,logger:a,onProgress:c,isCancelled:l}=t,u=new Map,d=new Map;for(let t=0;t<r.length&&!l?.();t++){const i=r[t];c?.({phase:"relations",message:`Checking relation ${i.collection}.${i.field}`,current:t+1,total:r.length,used_count:n.size});try{if(!await Nt(e,i.collection,u))continue;if(!await Tt(e,i.collection,i.field,d))continue;if(i.singleton){const t=await e(i.collection).select(i.field).first(),r=t?.[i.field];if(null==r)continue;"object"==typeof r&&r.id?n.add(wt(r.id)):n.add(wt(String(r)));continue}const t=await e(i.collection).distinct(i.field).whereNotNull(i.field);for(const e of t){const t=e?.[i.field];null!=t&&n.add(wt(String(t)))}}catch(e){a?.warn(`[storage-manager] unreferenced: skip relation ${i.collection}.${i.field}: ${e?.message||e}`)}t%5==4&&await Et()}if(!o||!i.length||l?.())return n.delete(""),n;for(let t=0;t<i.length&&!l?.();t++){const r=i[t];c?.({phase:"text",message:`Scanning ${r.collection}.${r.field}`,current:t+1,total:i.length,used_count:n.size});try{if(!await Nt(e,r.collection,u))continue;if(!await Tt(e,r.collection,r.field,d))continue;const o=At(s,r.collection),a=await Tt(e,r.collection,o,d);let f=null,p=0,g=0;for(;!l?.();){let s=e(r.collection).whereNotNull(r.field).limit(500);a?(s=s.select(o,r.field).orderBy(o,"asc"),null!=f&&(s=s.where(o,">",f))):s=s.select(r.field).offset(p);const l=await s;if(!l.length)break;for(const e of l){const t=St(e?.[r.field]);if(t){for(const e of vt(t))n.add(e);if("assets_and_uuids"===r.mode)for(const e of kt(t))n.add(e)}}if(g+=l.length,a?f=l[l.length-1]?.[o]??f:p+=l.length,g%1e4==0&&(c?.({phase:"text",message:`Scanning ${r.collection}.${r.field} (${g.toLocaleString()} rows)`,current:t+1,total:i.length,used_count:n.size}),await Et()),l.length<500)break}}catch(e){a?.warn(`[storage-manager] unreferenced: skip text ${r.collection}.${r.field}: ${e?.message||e}`)}}return n.delete(""),n}(e,{relations:u,textTargets:f,scanTextFields:o,schema:t,logger:n.logger,onProgress:c,isCancelled:l});if(l?.())return{files:[],meta:{total_files:0,used_count:p.size,unreferenced_count:0,unreferenced_bytes:0,relation_targets:u.length,text_targets:f.length,collections_checked:new Set([...u.map(e=>e.collection),...f.map(e=>e.collection)]).size,min_age_minutes:i,scan_text_fields:o,elapsed_ms:Date.now()-r,truncated:!1,ids_truncated:!1,ids:[]}};const g=i>0?new Date(Date.now()-6e4*i).toISOString():null,m={storage:n.storage,folder:n.folder,cutoff:g},h=Zt(e("directus_files").count({total:"*"}),m),_=await h.first(),y=Number(_?.total??_?.["count(*)"]??0)||0;c?.({phase:"files",message:`Walking File Library (${y.toLocaleString()} files)`,current:0,total:y,used_count:p.size,unreferenced_count:0});const w=[];let v=0,k=0,S=!1,b=0,$=null;for(;!l?.();){const t=Zt(e("directus_files").select("id","filesize").orderBy("id","asc").limit(5e3),m);$&&t.where("id",">",$);const n=await t;if(!n.length)break;for(const e of n){const t=String(e.id);p.has(wt(t))||(v++,k+=Number(e.filesize)||0,w.length<1e5?w.push(t):S=!0)}if(b+=n.length,$=String(n[n.length-1].id),c?.({phase:"files",message:`Checked ${b.toLocaleString()} / ${y.toLocaleString()} files`,current:b,total:y,used_count:p.size,unreferenced_count:v}),await Et(),n.length<5e3)break}c?.({phase:"finalize",message:"Preparing results",current:y,total:y,used_count:p.size,unreferenced_count:v});const z=w.slice(a,a+s);let j=[];if(z.length){const t=await e("directus_files").select("id","title","filename_download","filename_disk","storage","type","filesize","folder","uploaded_on").whereIn("id",z),n=new Map(t.map(e=>[wt(e.id),e]));j=z.map(e=>n.get(wt(e))).filter(Boolean)}const x=new Set([...u.map(e=>e.collection),...f.map(e=>e.collection)]).size;return{files:j,meta:{total_files:y,used_count:p.size,unreferenced_count:v,unreferenced_bytes:k,relation_targets:u.length,text_targets:f.length,collections_checked:x,min_age_minutes:i,scan_text_fields:o,elapsed_ms:Date.now()-r,truncated:a+s<w.length||S,ids_truncated:S,ids:w}}}async function Ft(e,t,n,r={}){const i=wt(n);if(!i)return!1;const o=It(t),s=new Map,a=new Map;for(const t of o)try{if(!await Nt(e,t.collection,s))continue;if(!await Tt(e,t.collection,t.field,a))continue;if(await e(t.collection).select(t.field).where(t.field,i).first())return!0}catch(e){r.logger?.warn(`[storage-manager] refcheck relation ${t.collection}.${t.field}: ${e?.message||e}`)}if(!1===r.scanTextFields)return!1;const c=Pt(await Ot(e,t),new Set(o.map(e=>`${e.collection}.${e.field}`))),l=`%${i}%`;for(const t of c)try{if(!await Nt(e,t.collection,s))continue;if(!await Tt(e,t.collection,t.field,a))continue;const n=await e(t.collection).select(t.field).where(t.field,"like",l).first();if(!n)continue;const r=St(n[t.field]);if(("assets_only"===t.mode?vt(r):[...vt(r),...kt(r)]).includes(i))return!0}catch(e){r.logger?.warn(`[storage-manager] refcheck text ${t.collection}.${t.field}: ${e?.message||e}`)}return!1}async function Dt(e,t,n,r,i,o={}){const s=n.FilesService;if(!s)return i.map(e=>({id:e,status:"failed",reason:"FilesService unavailable"}));const a=new s({accountability:r,schema:t}),c=[];for(const n of i){const r=wt(n);if(r)try{if(!await e("directus_files").select("id").where("id",r).first()){c.push({id:r,status:"skipped",reason:"not found"});continue}if(await Ft(e,t,r,{scanTextFields:o.scanTextFields,logger:o.logger})){c.push({id:r,status:"skipped",reason:"still referenced"});continue}await a.deleteOne(r),c.push({id:r,status:"deleted"})}catch(e){c.push({id:r,status:"failed",reason:e?.message||String(e)})}else c.push({id:n,status:"skipped",reason:"invalid id"})}return c}function Bt(e,t){return!!l(e.accountability)||(t.status(403).json({errors:[{message:"Admin access required",extensions:{code:"FORBIDDEN"}}]}),!1)}async function Ut(e,t){const n=Oe((await Te(e)).lifecycle??Ie);return{minAgeMinutes:void 0!==t.min_age_minutes?Number(t.min_age_minutes):n.scan_min_age_minutes,scanTextFields:void 0!==t.scan_text_fields?Boolean(t.scan_text_fields):n.scan_text_fields,storage:t.storage??null,folder:void 0===t.folder?void 0:t.folder,limit:t.limit,offset:t.offset}}function Rt(e,t){return!!l(e.accountability)||(t.status(403).json({errors:[{message:"Admin access required",extensions:{code:"FORBIDDEN"}}]}),!1)}async function Mt(e,t,n){if(!t)return[];if(!n)return[t];const r=await e("directus_folders").select("id","parent"),i=new Map;for(const e of r){const t=null==e.parent?null:String(e.parent),n=String(e.id);i.has(t)||i.set(t,[]),i.get(t).push(n)}const o=[],s=[String(t)];for(;s.length;){const e=s.pop();o.push(e);const t=i.get(e)||[];for(const e of t)s.push(e)}return o}function qt(e,t){const n=t.map(e=>B(e)).filter(Boolean);n.length&&e.where(function(){for(const e of n)this.orWhere("filename_disk",e).orWhere("filename_disk","like",`${e}/%`)})}async function Lt(e,t,n){const r=Array.isArray(n.file_ids)?n.file_ids.map(String).filter(Boolean):[],i=Array.isArray(n.source_folders)?n.source_folders.map(String):[];r.length&&i.length?e.where(function(){this.whereIn("id",r).orWhere(function(){qt(this,i)})}):r.length?e.whereIn("id",r):i.length&&qt(e,i),n.source_storage&&e.where("storage",String(n.source_storage));const o=null!=n.source_path?B(String(n.source_path)):"";if(o){if(!n.source_storage)return void e.whereRaw("1 = 0");const t=`${o}/`;!1===n.recursive?e.where("filename_disk","like",`${t}%`).whereNot("filename_disk","like",`${t}%/%`):e.where("filename_disk","like",`${t}%`)}if(void 0!==n.folder_id)if(null===n.folder_id||""===n.folder_id)e.whereNull("folder");else{const r=await Mt(t,String(n.folder_id),Boolean(n.recursive));0===r.length?e.where("folder",String(n.folder_id)):e.whereIn("folder",r)}}async function Wt(e,t){if(Array.isArray(t.file_ids)&&t.file_ids.length>0)return t.file_ids.map(String);const n=e("directus_files").select("id");await Lt(n,e,{...t,file_ids:void 0});return(await n).map(e=>String(e.id))}function Jt(e){return String(e?.client?.config?.client||e?.client?.dialect||"").toLowerCase()}async function Gt(e,t,n,r,i,o){if(o.length&&!i)return null;const s=B(r);let a;const c=[];if(i)s?(a=Jt(e).includes("sqlite")?"? || '/' || src.filename_disk":"CONCAT(?, '/', src.filename_disk)",c.push(s)):a="src.filename_disk";else{const t=function(e,t){const n=Jt(e);return n.includes("pg")||n.includes("cockroach")?`regexp_replace(${t}, '^.*/', '')`:n.includes("mysql")?`SUBSTRING_INDEX(${t}, '/', -1)`:n.includes("mssql")?`CASE WHEN CHARINDEX('/', ${t}) = 0 THEN ${t} ELSE RIGHT(${t}, CHARINDEX('/', REVERSE(${t})) - 1) END`:""}(e,"src.filename_disk");if(!t)return null;s?(a=Jt(e).includes("sqlite")?`? || '/' || (${t})`:`CONCAT(?, '/', ${t})`,c.push(s)):a=t}try{const r=t.clone().clearSelect().select("id","filename_disk").as("src"),i=await e.from(r).joinRaw(`inner join directus_files as occ on occ.storage = ? and occ.id <> src.id and occ.filename_disk = ${a}`,[n,...c]).count("* as n").first();return Number(i?.n??0)}catch{return null}}function Ht(e,t){if(!e)return 0;for(const n of t)if(null!=e[n]&&""!==e[n])return Number(e[n])||0;return 0}var Vt={id:"storage-manager",handler:(e,t)=>{const{database:r,env:i,logger:o,services:s,getSchema:u}=t;e.use(async(e,t,n)=>{try{await Fe(r,s,u,o),n()}catch(e){n(e)}}),function(e,t){const{database:n,logger:r,services:i,getSchema:o}=t;e.post("/unreferenced/scan",async(e,t,i)=>{try{if(!Bt(e,t))return;const i=e.body||{},s=await Ut(n,i),a=await o(),c=await Ct(n,a,{...s,logger:r});r.info(`[storage-manager] unreferenced scan: files=${c.meta.total_files} used≈${c.meta.used_count} unreferenced=${c.meta.unreferenced_count} relations=${c.meta.relation_targets} text=${c.meta.text_targets} ${c.meta.elapsed_ms}ms`),t.json({data:c.files,meta:c.meta})}catch(e){i(e)}}),e.post("/unreferenced/scan/stream",async(e,t,i)=>{try{if(!Bt(e,t))return;const i=e.body||{},s=await Ut(n,i),a=await o();t.status(200),t.setHeader("Content-Type","text/event-stream; charset=utf-8"),t.setHeader("Cache-Control","no-cache, no-transform"),t.setHeader("Connection","keep-alive"),t.setHeader("X-Accel-Buffering","no"),t.flushHeaders?.();let c=!1;const l=()=>{c=!0};e.on("close",l),t.on("close",l);const u=e=>{if(c)return;t.write(`data: ${JSON.stringify(e)}\n\n`);const n=t.flush;"function"==typeof n&&n.call(t)},d=setInterval(()=>{u({type:"heartbeat",ts:Date.now()})},12e3);try{u({type:"start",message:"Starting unreferenced scan"});const e=await Ct(n,a,{...s,logger:r,isCancelled:()=>c,onProgress:e=>{u({type:"progress",...e})}});if(c)return;r.info(`[storage-manager] unreferenced scan (stream): files=${e.meta.total_files} used≈${e.meta.used_count} unreferenced=${e.meta.unreferenced_count} ${e.meta.elapsed_ms}ms`),u({type:"done",data:e.files,meta:e.meta})}catch(e){u({type:"error",message:e instanceof Error?e.message:String(e)})}finally{clearInterval(d),c||t.end()}}catch(e){if(!t.headersSent)return void i(e);try{t.write(`data: ${JSON.stringify({type:"error",message:e instanceof Error?e.message:String(e)})}\n\n`),t.end()}catch{}}}),e.post("/unreferenced/delete",async(e,t,s)=>{try{if(!Bt(e,t))return;const s=Oe((await Te(n)).lifecycle??Ie),a=e.body||{},c=Array.isArray(a.file_ids)?a.file_ids.map(String).filter(Boolean):[];if(!c.length)return void t.status(400).json({errors:[{message:"Provide file_ids — at least one file to delete"}]});if(c.length>500)return void t.status(400).json({errors:[{message:"Delete at most 500 files per request"}]});const l=await o(),u=await Dt(n,l,i,e.accountability,c,{scanTextFields:void 0!==a.scan_text_fields?Boolean(a.scan_text_fields):s.scan_text_fields,logger:r});r.info(`[storage-manager] unreferenced delete: total=${u.length} deleted=${u.filter(e=>"deleted"===e.status).length}`),t.json({data:{total:u.length,deleted:u.filter(e=>"deleted"===e.status).length,skipped:u.filter(e=>"skipped"===e.status).length,failed:u.filter(e=>"failed"===e.status).length,results:u}})}catch(e){s(e)}}),e.post("/files/delete-if-unreferenced",async(e,t,s)=>{try{if(!e.accountability?.user&&!l(e.accountability))return void t.status(403).json({errors:[{message:"Authentication required",extensions:{code:"FORBIDDEN"}}]});const s=Oe((await Te(n)).lifecycle??Ie),a=e.body||{},c=(Array.isArray(a.file_ids)?a.file_ids:Array.isArray(a.ids)?a.ids:[]).map(String).filter(Boolean);if(!c.length)return void t.status(400).json({errors:[{message:"Provide file_ids"}]});if(c.length>50)return void t.status(400).json({errors:[{message:"At most 50 file ids per request"}]});const u=await o(),d=await Dt(n,u,i,e.accountability,c,{scanTextFields:s.scan_text_fields,logger:r});t.json({data:{total:d.length,deleted:d.filter(e=>"deleted"===e.status).length,skipped:d.filter(e=>"skipped"===e.status).length,failed:d.filter(e=>"failed"===e.status).length,results:d}})}catch(e){s(e)}})}(e,t),e.get("/storages",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=E(i),o=await Te(r),s=await N(r,n),a=await Promise.all(n.map(async e=>{const t=await Z(i,r,e,s.get(e));return t.mirror_directus_folders=Ke(Ce(o,e)),t}));t.json({data:a})}catch(e){n(e)}}),e.get("/update-check",async(e,t,n)=>{try{if(!Rt(e,t))return;const n="1"===String(e.query.force||""),r=await pt(n);t.json({data:r})}catch(e){n(e)}}),e.get("/storages/:location",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const o=await Z(i,r,n),s=await Te(r);o.mirror_directus_folders=Ke(Ce(s,n)),t.json({data:o})}catch(e){n(e)}}),e.get("/storages/:location/root-transforms",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const r="string"==typeof e.query.search?e.query.search:null,o=await ht({location:n,env:i,page:e.query.page,limit:e.query.limit,search:r});t.json({data:o.items,meta:{page:o.page,limit:o.limit,has_more:o.has_more}})}catch(e){n(e)}}),e.get("/storages/:location/root-transforms/count",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const r="string"==typeof e.query.search?e.query.search:null,o=null!=e.query.max?Number(e.query.max):void 0,s=await async function(e){const t=Math.min(Math.max(Number(e.max)||1e5,1),1e6);let n=0;for await(const r of gt(e.location,e.env))if(ke(r)&&Se(r,e.search??null)&&(n++,n>=t))return{count:t,capped:!0};return{count:n,capped:!1}}({location:n,env:i,search:r,max:o});t.json({data:s})}catch(e){n(e)}}),e.post("/storages/:location/root-transforms/delete-all",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const s=e.body||{},a=await async function(e){const t=(await g()).location(e.location),n=e.search??null,r=Boolean(e.dryRun);let i=0,o=0,s=0,a=0;const c=[];for await(const l of gt(e.location,e.env))if(ke(l)&&Se(l,n)){a++;try{if(await e.database("directus_files").select("id").where({storage:e.location,filename_disk:l}).first()){o++;continue}if(r){i++;continue}if(!await _(t,l)){o++;continue}await w(t,l),i++}catch(t){s++;const n=t?.message||String(t);c.push({filename_disk:l,error:n}),e.logger?.warn(`[storage-manager] Transform delete failed for ${l}: ${n}`)}}return!r&&i>0&&e.logger?.info(`[storage-manager] Deleted ${i} root transform(s) on ${e.location} (skipped ${o}, failed ${s})`),{dry_run:r,deleted:i,skipped:o,failed:s,scanned:a,errors:c.slice(0,20)}}({database:r,location:n,env:i,search:s.search??null,dryRun:Boolean(s.dry_run),logger:o});t.json({data:a})}catch(e){n(e)}}),e.get("/storages/:location/browse",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const o=B(String(e.query.path||"")),s=await H(r,n,o,i);t.json({data:s})}catch(e){n(e)}}),e.get("/storages/:location/folder-tree",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const o=await async function(e,t,n){const{folders:r}=await H(e,t,"",n);return r.map(e=>({name:e.name,path:e.path}))}(r,n,i);t.json({data:o})}catch(e){n(e)}}),e.post("/storages/:location/folders",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const r=e.body||{},o=await te(n,String(r.name||""),String(r.parent_path||""),i);t.json({data:o})}catch(e){if(e?.message&&/required|Invalid|cannot contain/i.test(e.message))return void t.status(400).json({errors:[{message:e.message}]});n(e)}}),e.delete("/storages/:location/folders",async(e,n,s)=>{try{if(!Rt(e,n))return;const s=String(e.params.location);if(!E(i).includes(s))return void n.status(404).json({errors:[{message:`Unknown storage location: ${s}`}]});const c=e.body||{},l=Array.isArray(c.paths)?c.paths.map(String):[];if(!l.length)return void n.status(400).json({errors:[{message:"Provide paths — at least one storage folder to delete"}]});const u="delete"===c.mode?"delete":"move";let d;try{const n=await t.getSchema(),r=t.services.FilesService;r&&(d=new r({accountability:e.accountability,schema:n}))}catch{d=void 0}const f=await async function(e,t,n,r,i,o){const s="delete"===o?.mode?"delete":"move",c=[],l=[];let u=0,d=0;const f=I(r,t),p=(await g()).location(t);for(const g of n){const n=B(g);if(!n){l.push({path:String(g),error:"Invalid path"});continue}const m=re(n);try{let g=0;if("delete"===s){const r=(await e("directus_files").select("id","filename_disk").where("storage",t).whereRaw("filename_disk LIKE ?",[`${n}/%`])).filter(e=>!M(String(e.filename_disk||""))),i=r.map(e=>String(e.id));if(i.length){if(o?.filesService)await o.filesService.deleteMany(i);else for(const t of r){const n=String(t.id),r=String(t.filename_disk||"");try{r&&await j(p,r)}catch{}await e("directus_files").where("id",n).delete()}g=i.length,d+=i.length}}else{const{moved:r,failed:o}=await se(e,t,n,m,i);if(u+=r,o>0){l.push({path:n,error:`Could not move ${o} registered file(s) to parent`});continue}}if("local"===f){const e=O(r,t);if(!e)throw new Error("Missing local root");const i=q(e,n);await a.rm(i,{recursive:!0,force:!0})}else try{for await(const e of v(p,`${n}/`)){const t=String(e||"").replace(/^[/\\]+/,"");if(t.startsWith(`${n}/`)&&M(t))try{await w(p,t)}catch{}}}catch{const e=`${n}/${F}`;await _(p,e)&&await w(p,e)}c.push(n),i?.info("delete"===s?`[storage-manager] Deleted storage folder “${n}” on ${t} (deleted ${g} registered file(s))`:`[storage-manager] Deleted storage folder “${n}” on ${t} (relocated files to parent)`)}catch(e){l.push({path:n,error:e?.message||String(e)})}}return{deleted:c,skipped:l,relocated:u,files_deleted:d}}(r,s,l,i,o,{mode:u,filesService:d});n.json({data:f})}catch(e){s(e)}}),e.patch("/storages/:location/folders",async(e,t,s)=>{try{if(!Rt(e,t))return;const s=String(e.params.location);if(!E(i).includes(s))return void t.status(404).json({errors:[{message:`Unknown storage location: ${s}`}]});const a=e.body||{},c=String(a.path||"");if(!c)return void t.status(400).json({errors:[{message:"Provide path — the storage folder to update"}]});const l=void 0!==a.name&&null!==a.name,u=Object.prototype.hasOwnProperty.call(a,"parent_path");if(!l&&!u)return void t.status(400).json({errors:[{message:"Provide name (rename) and/or parent_path (move)"}]});let d;if(l&&u){const e=String(a.name||"").trim(),t=U(String(a.parent_path??""),e);d=await oe(r,s,c,t,i,o)}else d=l?await async function(e,t,n,r,i,o){const s=B(n);if(!s)throw new Error("Folder path is required");const a=L(r);return oe(e,t,s,U(re(s),a),i,o)}(r,s,c,String(a.name||""),i,o):await async function(e,t,r,i,o,s){const a=B(r);if(!a)throw new Error("Folder path is required");return oe(e,t,a,U(B(i),n.posix.basename(a)),o,s)}(r,s,c,String(a.parent_path??""),i,o);t.json({data:d})}catch(e){if(e?.message&&/required|Invalid|cannot|already exists|Failed to relocate/i.test(e.message))return void t.status(400).json({errors:[{message:e.message}]});s(e)}}),e.post("/storages/:location/move-files",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const s=e.body||{},a=Array.isArray(s.file_ids)?s.file_ids.map(String):[],c=Array.isArray(s.source_folders)?s.source_folders.map(String):[];if(!a.length&&!c.length&&!s.source_storage)return void t.status(400).json({errors:[{message:"Provide file_ids or source_folders"}]});const l=a.length?await ne(r,n,a,String(s.target_path??""),o,i,c,Boolean(s.preserve_paths)):{moved:0,failed:0,skipped:0,results:[]};!1!==s.include_empty_folders&&(c.length||s.source_storage)&&await ee({database:r,sourceLocation:String(s.source_storage||n),targetLocation:n,env:i,targetPath:String(s.target_path??""),sourceFolders:c.length?c:void 0,removeSource:!0,logger:o}),t.json({data:l})}catch(e){n(e)}}),e.post("/storages/:location/place-file",async(e,t,o)=>{try{if(!Rt(e,t))return;const o=String(e.params.location);if(!E(i).includes(o))return void t.status(404).json({errors:[{message:`Unknown storage location: ${o}`}]});const s=e.body||{};if(!s.file_id)return void t.status(400).json({errors:[{message:"Provide file_id"}]});const a=await async function(e,t,r,i){const o=B(i);if(!o)return null;const s=await e("directus_files").select("id","storage","filename_disk","type").where("id",t).first();if(!s||String(s.storage)!==r)return null;const a=String(s.filename_disk||""),c=n.posix.basename(a);if(!a||a===`${o}/${c}`)return a;const l=(await ne(e,r,[t],o)).results[0];if("moved"===l?.status)return l.to;throw new Error(l?.error||"Failed to place file under storage path")}(r,String(s.file_id),o,String(s.target_path||""));t.json({data:{id:s.file_id,filename_disk:a}})}catch(e){t.status(400).json({errors:[{message:e?.message||"Place file failed"}]})}}),e.get("/storages/:location/orphans",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const o="string"==typeof e.query.path?e.query.path:"",s=await Ee(r,n,i,o);t.json({data:s.orphans,meta:{scanned:s.scanned,known:s.known,orphan_count:s.orphans.length,path:s.path||null}})}catch(e){n(e)}}),e.post("/storages/:location/import-orphans",async(e,t,s)=>{try{if(!Rt(e,t))return;const s=String(e.params.location);if(!E(i).includes(s))return void t.status(404).json({errors:[{message:`Unknown storage location: ${s}`}]});const a=e.body||{};let l=Array.isArray(a.filename_disks)?a.filename_disks.map(String):[];if(0===l.length){l=(await Ee(r,s,i,a.path||"")).orphans.map(e=>e.filename_disk)}if(0===l.length)return void t.json({data:{total:0,imported:0,skipped:0,failed:0,results:[]}});const u=await async function(e,t,r,i){const o=(await g()).location(t),s=[];for(const a of r){const r=String(a||"").trim();if(r&&!be(r))try{const a=await e("directus_files").select("id").where({storage:t,filename_disk:r}).first();if(a){s.push({filename_disk:r,id:String(a.id),status:"skipped",error:"Already in database"});continue}if(!await _(o,r)){s.push({filename_disk:r,status:"failed",error:"File not found on disk"});continue}const l=await y(o,r),u=xe(r);let d=u||c();u&&await e("directus_files").select("id").where({id:u}).first()&&(d=c());const f=new Date,p=n.basename(r),g=ze(r),m=je(r);let h=null,w=null;if(me(g)){const e=await _e(o,r);e&&(h=e.width,w=e.height)}await e("directus_files").insert({id:d,storage:t,filename_disk:r,filename_download:p,title:m,type:g,filesize:Number(l.size)||0,width:h,height:w,folder:i?.folder||null,uploaded_on:f,modified_on:f}),s.push({filename_disk:r,id:d,status:"imported"})}catch(e){s.push({filename_disk:r,status:"failed",error:e?.message||String(e)})}else s.push({filename_disk:r,status:"skipped",error:"Ignored path"})}return s}(r,s,l,{folder:void 0===a.folder?null:a.folder});o.info(`[storage-manager] import-orphans location=${s} total=${u.length} imported=${u.filter(e=>"imported"===e.status).length}`),t.json({data:{total:u.length,imported:u.filter(e=>"imported"===e.status).length,skipped:u.filter(e=>"skipped"===e.status).length,failed:u.filter(e=>"failed"===e.status).length,results:u}})}catch(e){s(e)}}),e.post("/storages/:location/delete-orphans",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location);if(!E(i).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const s=e.body||{},a=Array.isArray(s.filename_disks)?s.filename_disks.map(String).filter(Boolean):[];if(0===a.length)return void t.status(400).json({errors:[{message:"Provide filename_disks — at least one orphan to delete"}]});const c=await async function(e,t,n){const r=(await g()).location(t),i=[];for(const o of n){const n=String(o||"").trim();if(n&&!be(n))try{if(await e("directus_files").select("id").where({storage:t,filename_disk:n}).first()){i.push({filename_disk:n,status:"skipped",error:"Registered in Directus — use File Library to delete"});continue}if(!await _(r,n)){i.push({filename_disk:n,status:"skipped",error:"Not found on disk"});continue}await w(r,n),i.push({filename_disk:n,status:"deleted"})}catch(e){i.push({filename_disk:n,status:"failed",error:e?.message||String(e)})}else i.push({filename_disk:n,status:"skipped",error:n&&we(n)?"Generated thumbnail":"Ignored path"})}return i}(r,n,a);o.info(`[storage-manager] delete-orphans location=${n} total=${c.length} deleted=${c.filter(e=>"deleted"===e.status).length}`),t.json({data:{total:c.length,deleted:c.filter(e=>"deleted"===e.status).length,skipped:c.filter(e=>"skipped"===e.status).length,failed:c.filter(e=>"failed"===e.status).length,results:c}})}catch(e){n(e)}}),e.get("/files",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=e.query.storage?String(e.query.storage):null,i=void 0!==e.query.folder?"null"===e.query.folder||""===e.query.folder?null:String(e.query.folder):void 0,o=e.query.search?String(e.query.search).trim():"",s=function(e){if(!e)return null;try{const t="string"==typeof e?JSON.parse(e):e;if(t&&"object"==typeof t&&!Array.isArray(t))return t}catch{}return null}(e.query.filter),a="true"===String(e.query.recursive||""),c=Math.max(1,parseInt(String(e.query.page||"1"),10)||1),l=Math.min(200,Math.max(1,parseInt(String(e.query.limit||"50"),10)||50)),u=String(e.query.sort||"-uploaded_on"),d=r("directus_files").select("id","title","filename_download","filename_disk","storage","type","filesize","folder","uploaded_on","modified_on");if(n&&d.where("storage",n),void 0!==i)if(null===i)d.whereNull("folder");else if(a){const e=await Mt(r,i,!0);d.whereIn("folder",e)}else d.where("folder",i);if(o){const e=`%${o.replace(/[%_]/g,"\\$&")}%`;d.andWhere(t=>{t.where("title","like",e).orWhere("filename_download","like",e).orWhere("filename_disk","like",e)})}!function(e,t){if(!t)return;const n=(e,t)=>{if(t._and&&Array.isArray(t._and))for(const r of t._and)r&&"object"==typeof r&&n(e,r);else if(t._or&&Array.isArray(t._or))e.andWhere(e=>{for(const r of t._or)r&&"object"==typeof r&&e.orWhere(e=>n(e,r))});else for(const[n,r]of Object.entries(t)){if(n.startsWith("_"))continue;if(!r||"object"!=typeof r)continue;const t=r;"_eq"in t&&e.andWhere(n,t._eq),"_neq"in t&&e.andWhereNot(n,t._neq),"_null"in t&&e.whereNull(n),"_nnull"in t&&e.whereNotNull(n),"_contains"in t&&e.andWhere(n,"like",`%${String(t._contains)}%`),"_in"in t&&Array.isArray(t._in)&&e.whereIn(n,t._in)}};n(e,t)}(d,s);const f=d.clone().clearSelect().count({count:"*"}).first(),p=d.clone().clearSelect().sum({total_bytes:"filesize"}).first(),g=u.startsWith("-")?u.slice(1):u,m=u.startsWith("-")?"desc":"asc",h=new Set(["uploaded_on","modified_on","filename_download","filesize","title","storage","type"]).has(g)?g:"uploaded_on",_=await d.clone().orderBy(h,m).limit(l).offset((c-1)*l),y=await f,w=await p,v=Number(y?.count||0),k=Number(w?.total_bytes||0);t.json({data:_,meta:{total_count:v,filter_count:v,total_bytes:k,page:c,limit:l}})}catch(e){n(e)}}),e.get("/folders",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=void 0===e.query.parent?void 0:"null"===e.query.parent||""===e.query.parent?null:String(e.query.parent),i=e.query.storage?String(e.query.storage):null;let o=r("directus_folders").select("id","name","parent").orderBy("name","asc");null===n?o=o.whereNull("parent"):void 0!==n&&(o=o.where("parent",n));const s=await o,a=[];for(const e of s){const t=String(e.id);let n=r("directus_files").where("folder",t);i&&(n=n.andWhere("storage",i));const o=await n.select(r.raw("count(*) as file_count"),r.raw("coalesce(sum(filesize), 0) as total_bytes")).first(),s=await r("directus_folders").where("parent",t).count({count:"*"}).first();a.push({id:t,name:e.name,parent:null==e.parent?null:String(e.parent),file_count:Number(o?.file_count||0),total_bytes:Number(o?.total_bytes||0),child_count:Number(s?.count||0)})}let c=null;if(null==n){let e=r("directus_files").whereNull("folder");i&&(e=e.andWhere("storage",i));const t=await e.select(r.raw("count(*) as file_count"),r.raw("coalesce(sum(filesize), 0) as total_bytes")).first();c={file_count:Number(t?.file_count||0),total_bytes:Number(t?.total_bytes||0)}}t.json({data:a,meta:{root_files:c}})}catch(e){n(e)}}),e.get("/folders/tree",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=(await r("directus_folders").select("id","name","parent").orderBy("name","asc")).map(e=>({id:String(e.id),name:e.name,parent:null==e.parent?null:String(e.parent)}));t.json({data:n})}catch(e){n(e)}}),e.get("/folders/:id/path",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.id),i=[];let o=n;for(let e=0;e<50&&o;e++){const e=await r("directus_folders").select("id","name","parent").where({id:o}).first();if(!e)break;i.unshift({id:String(e.id),name:e.name}),o=null==e.parent?null:String(e.parent)}t.json({data:i})}catch(e){n(e)}}),e.post("/migrate/dry-run",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=e.body||{},o=String(n.target_storage||"").trim(),s=E(i);if(!o||!s.includes(o))return void t.status(400).json({errors:[{message:"Provide a valid target_storage"}]});const a=Array.isArray(n.file_ids)?n.file_ids.map(String).filter(Boolean):[],c=Array.isArray(n.source_folders)?n.source_folders.map(String):[];if(!(a.length>0||Boolean(n.source_storage)||void 0!==n.folder_id||c.length>0))return void t.status(400).json({errors:[{message:"Provide file_ids, source_storage, or folder_id"}]});const l=null!=n.target_path?String(n.target_path):"",u=Boolean(n.preserve_paths),d=r("directus_files");await Lt(d,r,n);const f=await d.clone().clearSelect().count("* as n").sum("filesize as bytes").first(),p=Ht(f,["n","count"]),g=Ht(f,["bytes","sum"]),m=(await d.clone().clearSelect().select("id","storage","filename_disk").limit(20)).map(e=>{const t=String(e.filename_disk||""),n=R(t,l,c,u);return{id:String(e.id),storage:String(e.storage),from:t,to:n}}),h=[...new Set(m.map(e=>e.to).filter(Boolean))],_=h.length?await r("directus_files").select("id","filename_disk").where({storage:o}).whereIn("filename_disk",h):[],y=new Map;for(const e of _)y.set(String(e.filename_disk),String(e.id));const w=[];for(const e of m){const t=y.get(e.to);w.push({from:`${e.storage}:${e.from}`,to:`${o}:${e.to}`,skipped:Boolean(t&&t!==e.id)})}const v=await Gt(r,d,o,l,u,c);t.json({data:{total_files:p,total_folders:0,empty_folders:0,total_bytes:g,skipped:v,samples:w}})}catch(e){n(e)}}),e.post("/migrate",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=e.body||{},s=String(n.target_storage||"").trim(),a="copy"===n.mode?"copy":"move"===n.mode?"move":null;if(!s||!a)return void t.status(400).json({errors:[{message:'target_storage and mode ("copy"|"move") are required'}]});const c=E(i);if(!c.includes(s))return void t.status(400).json({errors:[{message:`Unknown target storage: ${s}. Available: ${c.join(", ")}`}]});if(I(i,s),n.source_storage&&!c.includes(String(n.source_storage)))return void t.status(400).json({errors:[{message:`Unknown source storage: ${n.source_storage}`}]});if(!(Array.isArray(n.file_ids)&&n.file_ids.length>0||Boolean(n.source_storage)||void 0!==n.folder_id))return void t.status(400).json({errors:[{message:"Provide file_ids, source_storage, and/or folder_id to select files to migrate"}]});const l=await Wt(r,n);if(0===l.length)return void t.json({data:{mode:a,target_storage:s,total:0,succeeded:0,skipped:0,failed:0,results:[]}});const u=5e3;if(l.length>u)return void t.status(400).json({errors:[{message:`Selection contains ${l.length} files (max ${u} per request). Narrow the selection or run in batches.`}]});o.info(`[storage-manager] Starting ${a} of ${l.length} file(s) → ${s} (by ${e.accountability?.user||"unknown"})`);const d=await fe({fileIds:l,targetStorage:s,mode:a,keepSourceFileOnDisk:Boolean(n.keep_source_file_on_disk),targetPath:null!=n.target_path?String(n.target_path):void 0,sourceFolders:Array.isArray(n.source_folders)?n.source_folders.map(String):void 0,includeEmptyFolders:!1!==n.include_empty_folders,preservePaths:Boolean(n.preserve_paths),sourceStorage:n.source_storage?String(n.source_storage):void 0,sourcePath:null!=n.source_path?String(n.source_path):void 0,concurrency:n.concurrency,database:r,logger:o,env:i});t.json({data:d})}catch(e){n(e)}}),e.post("/migrate/stream",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=e.body||{},s=String(n.target_storage||"").trim(),a="copy"===n.mode?"copy":"move"===n.mode?"move":null;if(!s||!a)return void t.status(400).json({errors:[{message:'target_storage and mode ("copy"|"move") are required'}]});const c=E(i);if(!c.includes(s))return void t.status(400).json({errors:[{message:`Unknown target storage: ${s}. Available: ${c.join(", ")}`}]});if(I(i,s),n.source_storage&&!c.includes(String(n.source_storage)))return void t.status(400).json({errors:[{message:`Unknown source storage: ${n.source_storage}`}]});if(!(Array.isArray(n.file_ids)&&n.file_ids.length>0||Boolean(n.source_storage)||void 0!==n.folder_id))return void t.status(400).json({errors:[{message:"Provide file_ids, source_storage, and/or folder_id to select files to migrate"}]});const l=await Wt(r,n),u=5e3;if(l.length>u)return void t.status(400).json({errors:[{message:`Selection contains ${l.length} files (max ${u} per request). Narrow the selection or run in batches.`}]});t.status(200),t.setHeader("Content-Type","text/event-stream; charset=utf-8"),t.setHeader("Cache-Control","no-cache, no-transform"),t.setHeader("Connection","keep-alive"),t.setHeader("X-Accel-Buffering","no"),t.flushHeaders?.();let d=!1;const f=()=>{d=!0};e.on("close",f),t.on("close",f);const p=e=>{if(d)return;t.write(`data: ${JSON.stringify(e)}\n\n`);const n=t.flush;"function"==typeof n&&n.call(t)};o.info(`[storage-manager] Streaming ${a} of ${l.length} file(s) → ${s} (by ${e.accountability?.user||"unknown"})`);try{await fe({fileIds:l,targetStorage:s,mode:a,keepSourceFileOnDisk:Boolean(n.keep_source_file_on_disk),targetPath:null!=n.target_path?String(n.target_path):void 0,sourceFolders:Array.isArray(n.source_folders)?n.source_folders.map(String):void 0,includeEmptyFolders:!1!==n.include_empty_folders,preservePaths:Boolean(n.preserve_paths),sourceStorage:n.source_storage?String(n.source_storage):void 0,sourcePath:null!=n.source_path?String(n.source_path):void 0,concurrency:n.concurrency??1,database:r,logger:o,env:i,isCancelled:()=>d,onProgress:e=>p(e)})}catch(e){p({type:"error",message:e instanceof Error?e.message:String(e)})}d||t.end()}catch(e){if(!t.headersSent)return void n(e);try{t.write(`data: ${JSON.stringify({type:"error",message:e instanceof Error?e.message:String(e)})}\n\n`),t.end()}catch{}}}),e.post("/materialize/dry-run",async(e,t,o)=>{try{if(!Rt(e,t))return;const o=e.body||{},s="merge"===o.mode?"merge":"preserve",a=void 0===o.folder_id||null===o.folder_id||""===o.folder_id?null:String(o.folder_id),c=String(o.target_storage||"").trim();if("merge"===s&&!c)return void t.status(400).json({errors:[{message:'target_storage is required when mode is "merge"'}]});if("merge"===s){if(!E(i).includes(c))return void t.status(400).json({errors:[{message:`Unknown target storage: ${c}`}]})}const l=await async function(e){const t=await e.database("directus_folders").select("id","name","parent"),r=new Map(t.map(e=>[String(e.id),{...e,id:String(e.id),parent:e.parent?String(e.parent):null}])),i=await it(e.database,e.folderId);let o=e.database("directus_files").select("id","storage","filename_disk","filesize","folder").whereNotNull("filename_disk");e.recursive?null!==e.folderId&&(o=o.whereIn("folder",[e.folderId,...i])):o=null===e.folderId?o.whereNull("folder"):o.whereIn("folder",i);const s=await o,a=await g(),c=new Set;let l=0;const u=new Map,d=[];for(const t of s){const i="merge"===e.mode?String(e.targetStorage||""):String(t.storage),o=rt(t.folder?String(t.folder):null,r),s=n.posix.basename(String(t.filename_disk||"")),f=o?`${o}/${s}`:s,p=`${i}::${f}`;c.has(p)&&(l+=1),c.add(p);const g=String(t.filename_disk||"").replace(/\\/g,"/").replace(/^\/+/,"");if(t.storage!==i||g!==f)try{const e=a.location(i);await _(e,f)&&(l+=1)}catch{}d.length<25&&d.push({id:String(t.id),from:`${t.storage}:${t.filename_disk}`,to_storage:i,to_path:f});const m=u.get(i)||{files:0,bytes:0};m.files+=1,m.bytes+=Number(t.filesize)||0,u.set(i,m)}const f=new Set(s.map(e=>e.folder).filter(Boolean));return{folder_id:e.folderId,mode:e.mode,target_storage:"merge"===e.mode&&e.targetStorage||null,structure_only:Boolean(e.structureOnly),total_files:s.length,total_folders:f.size,total_bytes:s.reduce((e,t)=>e+(Number(t.filesize)||0),0),conflicts:l,samples:d,by_storage:Array.from(u.entries()).map(([e,t])=>({storage:e,files:t.files,bytes:t.bytes}))}}({database:r,folderId:a,mode:s,targetStorage:c||void 0,structureOnly:Boolean(o.structure_only),recursive:Boolean(o.recursive)});t.json({data:l})}catch(e){o(e)}}),e.post("/materialize",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=e.body||{},s="merge"===n.mode?"merge":"preserve",a=void 0===n.folder_id||null===n.folder_id||""===n.folder_id?null:String(n.folder_id),c=String(n.target_storage||"").trim();if("merge"===s&&!c)return void t.status(400).json({errors:[{message:'target_storage is required when mode is "merge"'}]});if("merge"===s){if(!E(i).includes(c))return void t.status(400).json({errors:[{message:`Unknown target storage: ${c}`}]})}const l=await ot({database:r,logger:o,folderId:a,mode:s,targetStorage:c||void 0,structureOnly:Boolean(n.structure_only),keepSourceFileOnDisk:Boolean(n.keep_source_file_on_disk),recursive:Boolean(n.recursive)});t.json({data:l})}catch(e){n(e)}}),e.post("/materialize/stream",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=e.body||{},s="merge"===n.mode?"merge":"preserve",a=void 0===n.folder_id||null===n.folder_id||""===n.folder_id?null:String(n.folder_id),c=String(n.target_storage||"").trim();if("merge"===s&&!c)return void t.status(400).json({errors:[{message:'target_storage is required when mode is "merge"'}]});if("merge"===s){if(!E(i).includes(c))return void t.status(400).json({errors:[{message:`Unknown target storage: ${c}`}]})}t.status(200),t.setHeader("Content-Type","text/event-stream; charset=utf-8"),t.setHeader("Cache-Control","no-cache, no-transform"),t.setHeader("Connection","keep-alive"),t.setHeader("X-Accel-Buffering","no"),t.flushHeaders?.();let l=!1;const u=()=>{l=!0};e.on("close",u),t.on("close",u);const d=e=>{if(l)return;t.write(`data: ${JSON.stringify(e)}\n\n`);const n=t.flush;"function"==typeof n&&n.call(t)};try{await ot({database:r,logger:o,folderId:a,mode:s,targetStorage:c||void 0,structureOnly:Boolean(n.structure_only),keepSourceFileOnDisk:Boolean(n.keep_source_file_on_disk),recursive:Boolean(n.recursive),isCancelled:()=>l,onProgress:e=>d(e)})}catch(e){d({type:"error",message:e instanceof Error?e.message:String(e)})}l||t.end()}catch(e){if(!t.headersSent)return void n(e);try{t.write(`data: ${JSON.stringify({type:"error",message:e instanceof Error?e.message:String(e)})}\n\n`),t.end()}catch{}}}),e.get("/settings",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=await Te(r);t.json({data:{locations:n.locations??{},lifecycle:Oe(n.lifecycle??Ie)}})}catch(e){n(e)}}),e.patch("/settings",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=e.body;if(!n||"object"!=typeof n.locations&&void 0===n.lifecycle)return void t.status(400).json({errors:[{message:'Body must contain a "locations" object and/or "lifecycle".'}]});const i=await r("directus_settings").select(C).first(),o=i?.[C],s="string"==typeof o?JSON.parse(o):o??{locations:{}},a={...s.locations??{}};if(n.locations&&"object"==typeof n.locations)for(const[e,t]of Object.entries(n.locations))a[e]={...D,...s.locations?.[e]??{},...t};const c={locations:a,...void 0!==s.name_mirror_claims?{name_mirror_claims:s.name_mirror_claims}:{},lifecycle:Oe(void 0!==n.lifecycle?{...Oe(s.lifecycle??Ie),...n.lifecycle}:s.lifecycle??Ie)};await r("directus_settings").update({[C]:JSON.stringify(c)}),Ne(),t.json({data:{locations:c.locations,lifecycle:c.lifecycle}})}catch(e){n(e)}}),e.delete("/settings/locations/:location",async(e,t,n)=>{try{if(!Rt(e,t))return;const n=String(e.params.location),i=await r("directus_settings").select(C).first(),o=i?.[C],s="string"==typeof o?JSON.parse(o):o??{locations:{}};delete s.locations[n],await r("directus_settings").update({[C]:JSON.stringify(s)}),Ne(),t.json({data:s})}catch(e){n(e)}})}};var Kt={id:"storage-manager-operation",handler:async(e,{env:t,database:n,logger:r})=>{const i="copy"===e.mode?"copy":"move",o=String(e.target_storage||"").trim();if(!o)throw new Error("target_storage is required");const s=E(t);if(!s.includes(o))throw new Error(`Unknown target storage "${o}". Available: ${s.join(", ")}`);let a=function(e){if(!e)return[];if(Array.isArray(e))return e.map(String).filter(Boolean);if("string"==typeof e){const t=e.trim();if(!t)return[];try{const e=JSON.parse(t);if(Array.isArray(e))return e.map(String).filter(Boolean)}catch{return[t]}}return[]}(e.file_ids);if(0===a.length){const t=n("directus_files").select("id");if(e.source_storage){const n=String(e.source_storage).trim();if(!s.includes(n))throw new Error(`Unknown source storage "${n}"`);t.where("storage",n)}if(e.folder_id){const r=await async function(e,t,n){if(!n)return[t];const r=await e("directus_folders").select("id","parent"),i=new Map;for(const e of r){const t=null==e.parent?null:String(e.parent),n=String(e.id);i.has(t)||i.set(t,[]),i.get(t).push(n)}const o=[],s=[String(t)];for(;s.length;){const e=s.pop();o.push(e);for(const t of i.get(e)||[])s.push(t)}return o}(n,String(e.folder_id),!1!==e.recursive);t.whereIn("folder",r)}if(!e.source_storage&&!e.folder_id)throw new Error("Provide file_ids, source_storage, and/or folder_id");a=(await t).map(e=>String(e.id))}const c=null!=e.concurrency?parseInt(String(e.concurrency),10):1;return r.info(`[storage-manager-operation] ${i} ${a.length} file(s) → ${o}`),await fe({fileIds:a,targetStorage:o,mode:i,concurrency:c,database:n,logger:r})}};const Xt=["interface","display","layout","module","panel","theme"],Yt=["hook","endpoint"],Qt=["operation"];function en(e,t,n){function r(n,r){var i;Object.defineProperty(n,"_zod",{value:n._zod??{},enumerable:!1}),(i=n._zod).traits??(i.traits=new Set),n._zod.traits.add(e),t(n,r);for(const e in s.prototype)e in n||Object.defineProperty(n,e,{value:s.prototype[e].bind(n)});n._zod.constr=s,n._zod.def=r}const i=n?.Parent??Object;class o extends i{}function s(e){var t;const i=n?.Parent?new o:this;r(i,e),(t=i._zod).deferred??(t.deferred=[]);for(const e of i._zod.deferred)e();return i}return Object.defineProperty(o,"name",{value:e}),Object.defineProperty(s,"init",{value:r}),Object.defineProperty(s,Symbol.hasInstance,{value:t=>!!(n?.Parent&&t instanceof n.Parent)||t?._zod?.traits?.has(e)}),Object.defineProperty(s,"name",{value:e}),s}class tn extends Error{constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}}class nn extends Error{constructor(e){super(`Encountered unidirectional transform during encode: ${e}`),this.name="ZodEncodeError"}}const rn={};function on(e){return rn}function sn(e,t){return"bigint"==typeof t?t.toString():t}function an(e){return{get value(){{const t=e();return Object.defineProperty(this,"value",{value:t}),t}}}}function cn(e){return null==e}function ln(e){const t=e.startsWith("^")?1:0,n=e.endsWith("$")?e.length-1:e.length;return e.slice(t,n)}const un=Symbol("evaluating");function dn(e,t,n){let r;Object.defineProperty(e,t,{get(){if(r!==un)return void 0===r&&(r=un,r=n()),r},set(n){Object.defineProperty(e,t,{value:n})},configurable:!0})}function fn(e,t,n){Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0})}function pn(...e){const t={};for(const n of e){const e=Object.getOwnPropertyDescriptors(n);Object.assign(t,e)}return Object.defineProperties({},t)}function gn(e){return JSON.stringify(e)}const mn="captureStackTrace"in Error?Error.captureStackTrace:(...e)=>{};function hn(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}const _n=an(()=>{if("undefined"!=typeof navigator&&navigator?.userAgent?.includes("Cloudflare"))return!1;try{return new Function(""),!0}catch(e){return!1}});function yn(e){if(!1===hn(e))return!1;const t=e.constructor;if(void 0===t)return!0;const n=t.prototype;return!1!==hn(n)&&!1!==Object.prototype.hasOwnProperty.call(n,"isPrototypeOf")}function wn(e){return yn(e)?{...e}:Array.isArray(e)?[...e]:e}const vn=new Set(["string","number","symbol"]);function kn(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Sn(e,t,n){const r=new e._zod.constr(t??e._zod.def);return t&&!n?.parent||(r._zod.parent=e),r}function bn(e){const t=e;if(!t)return{};if("string"==typeof t)return{error:()=>t};if(void 0!==t?.message){if(void 0!==t?.error)throw new Error("Cannot specify both `message` and `error` params");t.error=t.message}return delete t.message,"string"==typeof t.error?{...t,error:()=>t.error}:t}function $n(e,t=0){if(!0===e.aborted)return!0;for(let n=t;n<e.issues.length;n++)if(!0!==e.issues[n]?.continue)return!0;return!1}function zn(e,t){return t.map(t=>{var n;return(n=t).path??(n.path=[]),t.path.unshift(e),t})}function jn(e){return"string"==typeof e?e:e?.message}function xn(e,t,n){const r={...e,path:e.path??[]};if(!e.message){const i=jn(e.inst?._zod.def?.error?.(e))??jn(t?.error?.(e))??jn(n.customError?.(e))??jn(n.localeError?.(e))??"Invalid input";r.message=i}return delete r.inst,delete r.continue,t?.reportInput||delete r.input,r}function An(e){return Array.isArray(e)?"array":"string"==typeof e?"string":"unknown"}function En(...e){const[t,n,r]=e;return"string"==typeof t?{message:t,code:"custom",input:n,inst:r}:{...t}}const In=(e,t)=>{e.name="$ZodError",Object.defineProperty(e,"_zod",{value:e._zod,enumerable:!1}),Object.defineProperty(e,"issues",{value:t,enumerable:!1}),e.message=JSON.stringify(t,sn,2),Object.defineProperty(e,"toString",{value:()=>e.message,enumerable:!1})},On=en("$ZodError",In),Pn=en("$ZodError",In,{Parent:Error});const Nn=e=>(t,n,r,i)=>{const o=r?Object.assign(r,{async:!1}):{async:!1},s=t._zod.run({value:n,issues:[]},o);if(s instanceof Promise)throw new tn;if(s.issues.length){const t=new(i?.Err??e)(s.issues.map(e=>xn(e,o,on())));throw mn(t,i?.callee),t}return s.value},Tn=e=>async(t,n,r,i)=>{const o=r?Object.assign(r,{async:!0}):{async:!0};let s=t._zod.run({value:n,issues:[]},o);if(s instanceof Promise&&(s=await s),s.issues.length){const t=new(i?.Err??e)(s.issues.map(e=>xn(e,o,on())));throw mn(t,i?.callee),t}return s.value},Zn=e=>(t,n,r)=>{const i=r?{...r,async:!1}:{async:!1},o=t._zod.run({value:n,issues:[]},i);if(o instanceof Promise)throw new tn;return o.issues.length?{success:!1,error:new(e??On)(o.issues.map(e=>xn(e,i,on())))}:{success:!0,data:o.value}},Cn=Zn(Pn),Fn=e=>async(t,n,r)=>{const i=r?Object.assign(r,{async:!0}):{async:!0};let o=t._zod.run({value:n,issues:[]},i);return o instanceof Promise&&(o=await o),o.issues.length?{success:!1,error:new e(o.issues.map(e=>xn(e,i,on())))}:{success:!0,data:o.value}},Dn=Fn(Pn),Bn=e=>(t,n,r)=>{const i=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Nn(e)(t,n,i)},Un=e=>(t,n,r)=>Nn(e)(t,n,r),Rn=e=>async(t,n,r)=>{const i=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Tn(e)(t,n,i)},Mn=e=>async(t,n,r)=>Tn(e)(t,n,r),qn=e=>(t,n,r)=>{const i=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Zn(e)(t,n,i)},Ln=e=>(t,n,r)=>Zn(e)(t,n,r),Wn=e=>async(t,n,r)=>{const i=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Fn(e)(t,n,i)},Jn=e=>async(t,n,r)=>Fn(e)(t,n,r),Gn=/^[cC][^\s-]{8,}$/,Hn=/^[0-9a-z]+$/,Vn=/^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/,Kn=/^[0-9a-vA-V]{20}$/,Xn=/^[A-Za-z0-9]{27}$/,Yn=/^[a-zA-Z0-9_-]{21}$/,Qn=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/,er=/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/,tr=e=>e?new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${e}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`):/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/,nr=/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/;const rr=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,ir=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/,or=/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/,sr=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,ar=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,cr=/^[A-Za-z0-9_-]*$/,lr=/^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/,ur=/^\+(?:[0-9]){6,14}[0-9]$/,dr="(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))",fr=new RegExp(`^${dr}$`);function pr(e){const t="(?:[01]\\d|2[0-3]):[0-5]\\d";return"number"==typeof e.precision?-1===e.precision?`${t}`:0===e.precision?`${t}:[0-5]\\d`:`${t}:[0-5]\\d\\.\\d{${e.precision}}`:`${t}(?::[0-5]\\d(?:\\.\\d+)?)?`}const gr=/^(?:true|false)$/i,mr=/^[^A-Z]*$/,hr=/^[^a-z]*$/,_r=en("$ZodCheck",(e,t)=>{var n;e._zod??(e._zod={}),e._zod.def=t,(n=e._zod).onattach??(n.onattach=[])}),yr=en("$ZodCheckMaxLength",(e,t)=>{var n;_r.init(e,t),(n=e._zod.def).when??(n.when=e=>{const t=e.value;return!cn(t)&&void 0!==t.length}),e._zod.onattach.push(e=>{const n=e._zod.bag.maximum??Number.POSITIVE_INFINITY;t.maximum<n&&(e._zod.bag.maximum=t.maximum)}),e._zod.check=n=>{const r=n.value;if(r.length<=t.maximum)return;const i=An(r);n.issues.push({origin:i,code:"too_big",maximum:t.maximum,inclusive:!0,input:r,inst:e,continue:!t.abort})}}),wr=en("$ZodCheckMinLength",(e,t)=>{var n;_r.init(e,t),(n=e._zod.def).when??(n.when=e=>{const t=e.value;return!cn(t)&&void 0!==t.length}),e._zod.onattach.push(e=>{const n=e._zod.bag.minimum??Number.NEGATIVE_INFINITY;t.minimum>n&&(e._zod.bag.minimum=t.minimum)}),e._zod.check=n=>{const r=n.value;if(r.length>=t.minimum)return;const i=An(r);n.issues.push({origin:i,code:"too_small",minimum:t.minimum,inclusive:!0,input:r,inst:e,continue:!t.abort})}}),vr=en("$ZodCheckLengthEquals",(e,t)=>{var n;_r.init(e,t),(n=e._zod.def).when??(n.when=e=>{const t=e.value;return!cn(t)&&void 0!==t.length}),e._zod.onattach.push(e=>{const n=e._zod.bag;n.minimum=t.length,n.maximum=t.length,n.length=t.length}),e._zod.check=n=>{const r=n.value,i=r.length;if(i===t.length)return;const o=An(r),s=i>t.length;n.issues.push({origin:o,...s?{code:"too_big",maximum:t.length}:{code:"too_small",minimum:t.length},inclusive:!0,exact:!0,input:n.value,inst:e,continue:!t.abort})}}),kr=en("$ZodCheckStringFormat",(e,t)=>{var n,r;_r.init(e,t),e._zod.onattach.push(e=>{const n=e._zod.bag;n.format=t.format,t.pattern&&(n.patterns??(n.patterns=new Set),n.patterns.add(t.pattern))}),t.pattern?(n=e._zod).check??(n.check=n=>{t.pattern.lastIndex=0,t.pattern.test(n.value)||n.issues.push({origin:"string",code:"invalid_format",format:t.format,input:n.value,...t.pattern?{pattern:t.pattern.toString()}:{},inst:e,continue:!t.abort})}):(r=e._zod).check??(r.check=()=>{})}),Sr=en("$ZodCheckRegex",(e,t)=>{kr.init(e,t),e._zod.check=n=>{t.pattern.lastIndex=0,t.pattern.test(n.value)||n.issues.push({origin:"string",code:"invalid_format",format:"regex",input:n.value,pattern:t.pattern.toString(),inst:e,continue:!t.abort})}}),br=en("$ZodCheckLowerCase",(e,t)=>{t.pattern??(t.pattern=mr),kr.init(e,t)}),$r=en("$ZodCheckUpperCase",(e,t)=>{t.pattern??(t.pattern=hr),kr.init(e,t)}),zr=en("$ZodCheckIncludes",(e,t)=>{_r.init(e,t);const n=kn(t.includes),r=new RegExp("number"==typeof t.position?`^.{${t.position}}${n}`:n);t.pattern=r,e._zod.onattach.push(e=>{const t=e._zod.bag;t.patterns??(t.patterns=new Set),t.patterns.add(r)}),e._zod.check=n=>{n.value.includes(t.includes,t.position)||n.issues.push({origin:"string",code:"invalid_format",format:"includes",includes:t.includes,input:n.value,inst:e,continue:!t.abort})}}),jr=en("$ZodCheckStartsWith",(e,t)=>{_r.init(e,t);const n=new RegExp(`^${kn(t.prefix)}.*`);t.pattern??(t.pattern=n),e._zod.onattach.push(e=>{const t=e._zod.bag;t.patterns??(t.patterns=new Set),t.patterns.add(n)}),e._zod.check=n=>{n.value.startsWith(t.prefix)||n.issues.push({origin:"string",code:"invalid_format",format:"starts_with",prefix:t.prefix,input:n.value,inst:e,continue:!t.abort})}}),xr=en("$ZodCheckEndsWith",(e,t)=>{_r.init(e,t);const n=new RegExp(`.*${kn(t.suffix)}$`);t.pattern??(t.pattern=n),e._zod.onattach.push(e=>{const t=e._zod.bag;t.patterns??(t.patterns=new Set),t.patterns.add(n)}),e._zod.check=n=>{n.value.endsWith(t.suffix)||n.issues.push({origin:"string",code:"invalid_format",format:"ends_with",suffix:t.suffix,input:n.value,inst:e,continue:!t.abort})}}),Ar=en("$ZodCheckOverwrite",(e,t)=>{_r.init(e,t),e._zod.check=e=>{e.value=t.tx(e.value)}});class Er{constructor(e=[]){this.content=[],this.indent=0,this&&(this.args=e)}indented(e){this.indent+=1,e(this),this.indent-=1}write(e){if("function"==typeof e)return e(this,{execution:"sync"}),void e(this,{execution:"async"});const t=e.split("\n").filter(e=>e),n=Math.min(...t.map(e=>e.length-e.trimStart().length)),r=t.map(e=>e.slice(n)).map(e=>" ".repeat(2*this.indent)+e);for(const e of r)this.content.push(e)}compile(){const e=Function,t=this?.args;return new e(...t,[...(this?.content??[""]).map(e=>` ${e}`)].join("\n"))}}const Ir={major:4,minor:1,patch:12},Or=en("$ZodType",(e,t)=>{var n;e??(e={}),e._zod.def=t,e._zod.bag=e._zod.bag||{},e._zod.version=Ir;const r=[...e._zod.def.checks??[]];e._zod.traits.has("$ZodCheck")&&r.unshift(e);for(const t of r)for(const n of t._zod.onattach)n(e);if(0===r.length)(n=e._zod).deferred??(n.deferred=[]),e._zod.deferred?.push(()=>{e._zod.run=e._zod.parse});else{const t=(e,t,n)=>{let r,i=$n(e);for(const o of t){if(o._zod.def.when){if(!o._zod.def.when(e))continue}else if(i)continue;const t=e.issues.length,s=o._zod.check(e);if(s instanceof Promise&&!1===n?.async)throw new tn;if(r||s instanceof Promise)r=(r??Promise.resolve()).then(async()=>{await s;e.issues.length!==t&&(i||(i=$n(e,t)))});else{if(e.issues.length===t)continue;i||(i=$n(e,t))}}return r?r.then(()=>e):e},n=(n,i,o)=>{if($n(n))return n.aborted=!0,n;const s=t(i,r,o);if(s instanceof Promise){if(!1===o.async)throw new tn;return s.then(t=>e._zod.parse(t,o))}return e._zod.parse(s,o)};e._zod.run=(i,o)=>{if(o.skipChecks)return e._zod.parse(i,o);if("backward"===o.direction){const t=e._zod.parse({value:i.value,issues:[]},{...o,skipChecks:!0});return t instanceof Promise?t.then(e=>n(e,i,o)):n(t,i,o)}const s=e._zod.parse(i,o);if(s instanceof Promise){if(!1===o.async)throw new tn;return s.then(e=>t(e,r,o))}return t(s,r,o)}}e["~standard"]={validate:t=>{try{const n=Cn(e,t);return n.success?{value:n.data}:{issues:n.error?.issues}}catch(n){return Dn(e,t).then(e=>e.success?{value:e.data}:{issues:e.error?.issues})}},vendor:"zod",version:1}}),Pr=en("$ZodString",(e,t)=>{var n;Or.init(e,t),e._zod.pattern=[...e?._zod.bag?.patterns??[]].pop()??(n=e._zod.bag,new RegExp(`^${n?`[\\s\\S]{${n?.minimum??0},${n?.maximum??""}}`:"[\\s\\S]*"}$`)),e._zod.parse=(n,r)=>{if(t.coerce)try{n.value=String(n.value)}catch(r){}return"string"==typeof n.value||n.issues.push({expected:"string",code:"invalid_type",input:n.value,inst:e}),n}}),Nr=en("$ZodStringFormat",(e,t)=>{kr.init(e,t),Pr.init(e,t)}),Tr=en("$ZodGUID",(e,t)=>{t.pattern??(t.pattern=er),Nr.init(e,t)}),Zr=en("$ZodUUID",(e,t)=>{if(t.version){const e={v1:1,v2:2,v3:3,v4:4,v5:5,v6:6,v7:7,v8:8}[t.version];if(void 0===e)throw new Error(`Invalid UUID version: "${t.version}"`);t.pattern??(t.pattern=tr(e))}else t.pattern??(t.pattern=tr());Nr.init(e,t)}),Cr=en("$ZodEmail",(e,t)=>{t.pattern??(t.pattern=nr),Nr.init(e,t)}),Fr=en("$ZodURL",(e,t)=>{Nr.init(e,t),e._zod.check=n=>{try{const r=n.value.trim(),i=new URL(r);return t.hostname&&(t.hostname.lastIndex=0,t.hostname.test(i.hostname)||n.issues.push({code:"invalid_format",format:"url",note:"Invalid hostname",pattern:lr.source,input:n.value,inst:e,continue:!t.abort})),t.protocol&&(t.protocol.lastIndex=0,t.protocol.test(i.protocol.endsWith(":")?i.protocol.slice(0,-1):i.protocol)||n.issues.push({code:"invalid_format",format:"url",note:"Invalid protocol",pattern:t.protocol.source,input:n.value,inst:e,continue:!t.abort})),void(t.normalize?n.value=i.href:n.value=r)}catch(r){n.issues.push({code:"invalid_format",format:"url",input:n.value,inst:e,continue:!t.abort})}}}),Dr=en("$ZodEmoji",(e,t)=>{t.pattern??(t.pattern=new RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$","u")),Nr.init(e,t)}),Br=en("$ZodNanoID",(e,t)=>{t.pattern??(t.pattern=Yn),Nr.init(e,t)}),Ur=en("$ZodCUID",(e,t)=>{t.pattern??(t.pattern=Gn),Nr.init(e,t)}),Rr=en("$ZodCUID2",(e,t)=>{t.pattern??(t.pattern=Hn),Nr.init(e,t)}),Mr=en("$ZodULID",(e,t)=>{t.pattern??(t.pattern=Vn),Nr.init(e,t)}),qr=en("$ZodXID",(e,t)=>{t.pattern??(t.pattern=Kn),Nr.init(e,t)}),Lr=en("$ZodKSUID",(e,t)=>{t.pattern??(t.pattern=Xn),Nr.init(e,t)}),Wr=en("$ZodISODateTime",(e,t)=>{t.pattern??(t.pattern=function(e){const t=pr({precision:e.precision}),n=["Z"];e.local&&n.push(""),e.offset&&n.push("([+-](?:[01]\\d|2[0-3]):[0-5]\\d)");const r=`${t}(?:${n.join("|")})`;return new RegExp(`^${dr}T(?:${r})$`)}(t)),Nr.init(e,t)}),Jr=en("$ZodISODate",(e,t)=>{t.pattern??(t.pattern=fr),Nr.init(e,t)}),Gr=en("$ZodISOTime",(e,t)=>{t.pattern??(t.pattern=new RegExp(`^${pr(t)}$`)),Nr.init(e,t)}),Hr=en("$ZodISODuration",(e,t)=>{t.pattern??(t.pattern=Qn),Nr.init(e,t)}),Vr=en("$ZodIPv4",(e,t)=>{t.pattern??(t.pattern=rr),Nr.init(e,t),e._zod.onattach.push(e=>{e._zod.bag.format="ipv4"})}),Kr=en("$ZodIPv6",(e,t)=>{t.pattern??(t.pattern=ir),Nr.init(e,t),e._zod.onattach.push(e=>{e._zod.bag.format="ipv6"}),e._zod.check=n=>{try{new URL(`http://[${n.value}]`)}catch{n.issues.push({code:"invalid_format",format:"ipv6",input:n.value,inst:e,continue:!t.abort})}}}),Xr=en("$ZodCIDRv4",(e,t)=>{t.pattern??(t.pattern=or),Nr.init(e,t)}),Yr=en("$ZodCIDRv6",(e,t)=>{t.pattern??(t.pattern=sr),Nr.init(e,t),e._zod.check=n=>{const r=n.value.split("/");try{if(2!==r.length)throw new Error;const[e,t]=r;if(!t)throw new Error;const n=Number(t);if(`${n}`!==t)throw new Error;if(n<0||n>128)throw new Error;new URL(`http://[${e}]`)}catch{n.issues.push({code:"invalid_format",format:"cidrv6",input:n.value,inst:e,continue:!t.abort})}}});function Qr(e){if(""===e)return!0;if(e.length%4!=0)return!1;try{return atob(e),!0}catch{return!1}}const ei=en("$ZodBase64",(e,t)=>{t.pattern??(t.pattern=ar),Nr.init(e,t),e._zod.onattach.push(e=>{e._zod.bag.contentEncoding="base64"}),e._zod.check=n=>{Qr(n.value)||n.issues.push({code:"invalid_format",format:"base64",input:n.value,inst:e,continue:!t.abort})}});const ti=en("$ZodBase64URL",(e,t)=>{t.pattern??(t.pattern=cr),Nr.init(e,t),e._zod.onattach.push(e=>{e._zod.bag.contentEncoding="base64url"}),e._zod.check=n=>{(function(e){if(!cr.test(e))return!1;const t=e.replace(/[-_]/g,e=>"-"===e?"+":"/");return Qr(t.padEnd(4*Math.ceil(t.length/4),"="))})(n.value)||n.issues.push({code:"invalid_format",format:"base64url",input:n.value,inst:e,continue:!t.abort})}}),ni=en("$ZodE164",(e,t)=>{t.pattern??(t.pattern=ur),Nr.init(e,t)});const ri=en("$ZodJWT",(e,t)=>{Nr.init(e,t),e._zod.check=n=>{(function(e,t=null){try{const n=e.split(".");if(3!==n.length)return!1;const[r]=n;if(!r)return!1;const i=JSON.parse(atob(r));return!("typ"in i&&"JWT"!==i?.typ||!i.alg||t&&(!("alg"in i)||i.alg!==t))}catch{return!1}})(n.value,t.alg)||n.issues.push({code:"invalid_format",format:"jwt",input:n.value,inst:e,continue:!t.abort})}}),ii=en("$ZodBoolean",(e,t)=>{Or.init(e,t),e._zod.pattern=gr,e._zod.parse=(n,r)=>{if(t.coerce)try{n.value=Boolean(n.value)}catch(e){}const i=n.value;return"boolean"==typeof i||n.issues.push({expected:"boolean",code:"invalid_type",input:i,inst:e}),n}}),oi=en("$ZodUnknown",(e,t)=>{Or.init(e,t),e._zod.parse=e=>e}),si=en("$ZodNever",(e,t)=>{Or.init(e,t),e._zod.parse=(t,n)=>(t.issues.push({expected:"never",code:"invalid_type",input:t.value,inst:e}),t)});function ai(e,t,n){e.issues.length&&t.issues.push(...zn(n,e.issues)),t.value[n]=e.value}const ci=en("$ZodArray",(e,t)=>{Or.init(e,t),e._zod.parse=(n,r)=>{const i=n.value;if(!Array.isArray(i))return n.issues.push({expected:"array",code:"invalid_type",input:i,inst:e}),n;n.value=Array(i.length);const o=[];for(let e=0;e<i.length;e++){const s=i[e],a=t.element._zod.run({value:s,issues:[]},r);a instanceof Promise?o.push(a.then(t=>ai(t,n,e))):ai(a,n,e)}return o.length?Promise.all(o).then(()=>n):n}});function li(e,t,n,r){e.issues.length&&t.issues.push(...zn(n,e.issues)),void 0===e.value?n in r&&(t.value[n]=void 0):t.value[n]=e.value}function ui(e){const t=Object.keys(e.shape);for(const n of t)if(!e.shape?.[n]?._zod?.traits?.has("$ZodType"))throw new Error(`Invalid element at key "${n}": expected a Zod schema`);const n=(r=e.shape,Object.keys(r).filter(e=>"optional"===r[e]._zod.optin&&"optional"===r[e]._zod.optout));var r;return{...e,keys:t,keySet:new Set(t),numKeys:t.length,optionalKeys:new Set(n)}}function di(e,t,n,r,i,o){const s=[],a=i.keySet,c=i.catchall._zod,l=c.def.type;for(const i of Object.keys(t)){if(a.has(i))continue;if("never"===l){s.push(i);continue}const o=c.run({value:t[i],issues:[]},r);o instanceof Promise?e.push(o.then(e=>li(e,n,i,t))):li(o,n,i,t)}return s.length&&n.issues.push({code:"unrecognized_keys",keys:s,input:t,inst:o}),e.length?Promise.all(e).then(()=>n):n}const fi=en("$ZodObject",(e,t)=>{Or.init(e,t);const n=Object.getOwnPropertyDescriptor(t,"shape");if(!n?.get){const e=t.shape;Object.defineProperty(t,"shape",{get:()=>{const n={...e};return Object.defineProperty(t,"shape",{value:n}),n}})}const r=an(()=>ui(t));dn(e._zod,"propValues",()=>{const e=t.shape,n={};for(const t in e){const r=e[t]._zod;if(r.values){n[t]??(n[t]=new Set);for(const e of r.values)n[t].add(e)}}return n});const i=hn,o=t.catchall;let s;e._zod.parse=(t,n)=>{s??(s=r.value);const a=t.value;if(!i(a))return t.issues.push({expected:"object",code:"invalid_type",input:a,inst:e}),t;t.value={};const c=[],l=s.shape;for(const e of s.keys){const r=l[e]._zod.run({value:a[e],issues:[]},n);r instanceof Promise?c.push(r.then(n=>li(n,t,e,a))):li(r,t,e,a)}return o?di(c,a,t,n,r.value,e):c.length?Promise.all(c).then(()=>t):t}}),pi=en("$ZodObjectJIT",(e,t)=>{fi.init(e,t);const n=e._zod.parse,r=an(()=>ui(t));let i;const o=hn,s=!rn.jitless,a=s&&_n.value,c=t.catchall;let l;e._zod.parse=(u,d)=>{l??(l=r.value);const f=u.value;return o(f)?s&&a&&!1===d?.async&&!0!==d.jitless?(i||(i=(e=>{const t=new Er(["shape","payload","ctx"]),n=r.value,i=e=>{const t=gn(e);return`shape[${t}]._zod.run({ value: input[${t}], issues: [] }, ctx)`};t.write("const input = payload.value;");const o=Object.create(null);let s=0;for(const e of n.keys)o[e]="key_"+s++;t.write("const newResult = {};");for(const e of n.keys){const n=o[e],r=gn(e);t.write(`const ${n} = ${i(e)};`),t.write(`\n if (${n}.issues.length) {\n payload.issues = payload.issues.concat(${n}.issues.map(iss => ({\n ...iss,\n path: iss.path ? [${r}, ...iss.path] : [${r}]\n })));\n }\n \n \n if (${n}.value === undefined) {\n if (${r} in input) {\n newResult[${r}] = undefined;\n }\n } else {\n newResult[${r}] = ${n}.value;\n }\n \n `)}t.write("payload.value = newResult;"),t.write("return payload;");const a=t.compile();return(t,n)=>a(e,t,n)})(t.shape)),u=i(u,d),c?di([],f,u,d,l,e):u):n(u,d):(u.issues.push({expected:"object",code:"invalid_type",input:f,inst:e}),u)}});function gi(e,t,n,r){for(const n of e)if(0===n.issues.length)return t.value=n.value,t;const i=e.filter(e=>!$n(e));return 1===i.length?(t.value=i[0].value,i[0]):(t.issues.push({code:"invalid_union",input:t.value,inst:n,errors:e.map(e=>e.issues.map(e=>xn(e,r,on())))}),t)}const mi=en("$ZodUnion",(e,t)=>{Or.init(e,t),dn(e._zod,"optin",()=>t.options.some(e=>"optional"===e._zod.optin)?"optional":void 0),dn(e._zod,"optout",()=>t.options.some(e=>"optional"===e._zod.optout)?"optional":void 0),dn(e._zod,"values",()=>{if(t.options.every(e=>e._zod.values))return new Set(t.options.flatMap(e=>Array.from(e._zod.values)))}),dn(e._zod,"pattern",()=>{if(t.options.every(e=>e._zod.pattern)){const e=t.options.map(e=>e._zod.pattern);return new RegExp(`^(${e.map(e=>ln(e.source)).join("|")})$`)}});const n=1===t.options.length,r=t.options[0]._zod.run;e._zod.parse=(i,o)=>{if(n)return r(i,o);let s=!1;const a=[];for(const e of t.options){const t=e._zod.run({value:i.value,issues:[]},o);if(t instanceof Promise)a.push(t),s=!0;else{if(0===t.issues.length)return t;a.push(t)}}return s?Promise.all(a).then(t=>gi(t,i,e,o)):gi(a,i,e,o)}}),hi=en("$ZodIntersection",(e,t)=>{Or.init(e,t),e._zod.parse=(e,n)=>{const r=e.value,i=t.left._zod.run({value:r,issues:[]},n),o=t.right._zod.run({value:r,issues:[]},n);return i instanceof Promise||o instanceof Promise?Promise.all([i,o]).then(([t,n])=>yi(e,t,n)):yi(e,i,o)}});function _i(e,t){if(e===t)return{valid:!0,data:e};if(e instanceof Date&&t instanceof Date&&+e===+t)return{valid:!0,data:e};if(yn(e)&&yn(t)){const n=Object.keys(t),r=Object.keys(e).filter(e=>-1!==n.indexOf(e)),i={...e,...t};for(const n of r){const r=_i(e[n],t[n]);if(!r.valid)return{valid:!1,mergeErrorPath:[n,...r.mergeErrorPath]};i[n]=r.data}return{valid:!0,data:i}}if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return{valid:!1,mergeErrorPath:[]};const n=[];for(let r=0;r<e.length;r++){const i=_i(e[r],t[r]);if(!i.valid)return{valid:!1,mergeErrorPath:[r,...i.mergeErrorPath]};n.push(i.data)}return{valid:!0,data:n}}return{valid:!1,mergeErrorPath:[]}}function yi(e,t,n){if(t.issues.length&&e.issues.push(...t.issues),n.issues.length&&e.issues.push(...n.issues),$n(e))return e;const r=_i(t.value,n.value);if(!r.valid)throw new Error(`Unmergable intersection. Error path: ${JSON.stringify(r.mergeErrorPath)}`);return e.value=r.data,e}const wi=en("$ZodRecord",(e,t)=>{Or.init(e,t),e._zod.parse=(n,r)=>{const i=n.value;if(!yn(i))return n.issues.push({expected:"record",code:"invalid_type",input:i,inst:e}),n;const o=[];if(t.keyType._zod.values){const s=t.keyType._zod.values;n.value={};for(const e of s)if("string"==typeof e||"number"==typeof e||"symbol"==typeof e){const s=t.valueType._zod.run({value:i[e],issues:[]},r);s instanceof Promise?o.push(s.then(t=>{t.issues.length&&n.issues.push(...zn(e,t.issues)),n.value[e]=t.value})):(s.issues.length&&n.issues.push(...zn(e,s.issues)),n.value[e]=s.value)}let a;for(const e in i)s.has(e)||(a=a??[],a.push(e));a&&a.length>0&&n.issues.push({code:"unrecognized_keys",input:i,inst:e,keys:a})}else{n.value={};for(const s of Reflect.ownKeys(i)){if("__proto__"===s)continue;const a=t.keyType._zod.run({value:s,issues:[]},r);if(a instanceof Promise)throw new Error("Async schemas not supported in object keys currently");if(a.issues.length){n.issues.push({code:"invalid_key",origin:"record",issues:a.issues.map(e=>xn(e,r,on())),input:s,path:[s],inst:e}),n.value[a.value]=a.value;continue}const c=t.valueType._zod.run({value:i[s],issues:[]},r);c instanceof Promise?o.push(c.then(e=>{e.issues.length&&n.issues.push(...zn(s,e.issues)),n.value[a.value]=e.value})):(c.issues.length&&n.issues.push(...zn(s,c.issues)),n.value[a.value]=c.value)}}return o.length?Promise.all(o).then(()=>n):n}}),vi=en("$ZodEnum",(e,t)=>{Or.init(e,t);const n=function(e){const t=Object.values(e).filter(e=>"number"==typeof e);return Object.entries(e).filter(([e,n])=>-1===t.indexOf(+e)).map(([e,t])=>t)}(t.entries),r=new Set(n);e._zod.values=r,e._zod.pattern=new RegExp(`^(${n.filter(e=>vn.has(typeof e)).map(e=>"string"==typeof e?kn(e):e.toString()).join("|")})$`),e._zod.parse=(t,i)=>{const o=t.value;return r.has(o)||t.issues.push({code:"invalid_value",values:n,input:o,inst:e}),t}}),ki=en("$ZodLiteral",(e,t)=>{if(Or.init(e,t),0===t.values.length)throw new Error("Cannot create literal schema with no valid values");e._zod.values=new Set(t.values),e._zod.pattern=new RegExp(`^(${t.values.map(e=>"string"==typeof e?kn(e):e?kn(e.toString()):String(e)).join("|")})$`),e._zod.parse=(n,r)=>{const i=n.value;return e._zod.values.has(i)||n.issues.push({code:"invalid_value",values:t.values,input:i,inst:e}),n}}),Si=en("$ZodTransform",(e,t)=>{Or.init(e,t),e._zod.parse=(n,r)=>{if("backward"===r.direction)throw new nn(e.constructor.name);const i=t.transform(n.value,n);if(r.async){return(i instanceof Promise?i:Promise.resolve(i)).then(e=>(n.value=e,n))}if(i instanceof Promise)throw new tn;return n.value=i,n}});function bi(e,t){return e.issues.length&&void 0===t?{issues:[],value:void 0}:e}const $i=en("$ZodOptional",(e,t)=>{Or.init(e,t),e._zod.optin="optional",e._zod.optout="optional",dn(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),dn(e._zod,"pattern",()=>{const e=t.innerType._zod.pattern;return e?new RegExp(`^(${ln(e.source)})?$`):void 0}),e._zod.parse=(e,n)=>{if("optional"===t.innerType._zod.optin){const r=t.innerType._zod.run(e,n);return r instanceof Promise?r.then(t=>bi(t,e.value)):bi(r,e.value)}return void 0===e.value?e:t.innerType._zod.run(e,n)}}),zi=en("$ZodNullable",(e,t)=>{Or.init(e,t),dn(e._zod,"optin",()=>t.innerType._zod.optin),dn(e._zod,"optout",()=>t.innerType._zod.optout),dn(e._zod,"pattern",()=>{const e=t.innerType._zod.pattern;return e?new RegExp(`^(${ln(e.source)}|null)$`):void 0}),dn(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,null]):void 0),e._zod.parse=(e,n)=>null===e.value?e:t.innerType._zod.run(e,n)}),ji=en("$ZodDefault",(e,t)=>{Or.init(e,t),e._zod.optin="optional",dn(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(e,n)=>{if("backward"===n.direction)return t.innerType._zod.run(e,n);if(void 0===e.value)return e.value=t.defaultValue,e;const r=t.innerType._zod.run(e,n);return r instanceof Promise?r.then(e=>xi(e,t)):xi(r,t)}});function xi(e,t){return void 0===e.value&&(e.value=t.defaultValue),e}const Ai=en("$ZodPrefault",(e,t)=>{Or.init(e,t),e._zod.optin="optional",dn(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(e,n)=>("backward"===n.direction||void 0===e.value&&(e.value=t.defaultValue),t.innerType._zod.run(e,n))}),Ei=en("$ZodNonOptional",(e,t)=>{Or.init(e,t),dn(e._zod,"values",()=>{const e=t.innerType._zod.values;return e?new Set([...e].filter(e=>void 0!==e)):void 0}),e._zod.parse=(n,r)=>{const i=t.innerType._zod.run(n,r);return i instanceof Promise?i.then(t=>Ii(t,e)):Ii(i,e)}});function Ii(e,t){return e.issues.length||void 0!==e.value||e.issues.push({code:"invalid_type",expected:"nonoptional",input:e.value,inst:t}),e}const Oi=en("$ZodCatch",(e,t)=>{Or.init(e,t),dn(e._zod,"optin",()=>t.innerType._zod.optin),dn(e._zod,"optout",()=>t.innerType._zod.optout),dn(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(e,n)=>{if("backward"===n.direction)return t.innerType._zod.run(e,n);const r=t.innerType._zod.run(e,n);return r instanceof Promise?r.then(r=>(e.value=r.value,r.issues.length&&(e.value=t.catchValue({...e,error:{issues:r.issues.map(e=>xn(e,n,on()))},input:e.value}),e.issues=[]),e)):(e.value=r.value,r.issues.length&&(e.value=t.catchValue({...e,error:{issues:r.issues.map(e=>xn(e,n,on()))},input:e.value}),e.issues=[]),e)}}),Pi=en("$ZodPipe",(e,t)=>{Or.init(e,t),dn(e._zod,"values",()=>t.in._zod.values),dn(e._zod,"optin",()=>t.in._zod.optin),dn(e._zod,"optout",()=>t.out._zod.optout),dn(e._zod,"propValues",()=>t.in._zod.propValues),e._zod.parse=(e,n)=>{if("backward"===n.direction){const r=t.out._zod.run(e,n);return r instanceof Promise?r.then(e=>Ni(e,t.in,n)):Ni(r,t.in,n)}const r=t.in._zod.run(e,n);return r instanceof Promise?r.then(e=>Ni(e,t.out,n)):Ni(r,t.out,n)}});function Ni(e,t,n){return e.issues.length?(e.aborted=!0,e):t._zod.run({value:e.value,issues:e.issues},n)}const Ti=en("$ZodReadonly",(e,t)=>{Or.init(e,t),dn(e._zod,"propValues",()=>t.innerType._zod.propValues),dn(e._zod,"values",()=>t.innerType._zod.values),dn(e._zod,"optin",()=>t.innerType._zod.optin),dn(e._zod,"optout",()=>t.innerType._zod.optout),e._zod.parse=(e,n)=>{if("backward"===n.direction)return t.innerType._zod.run(e,n);const r=t.innerType._zod.run(e,n);return r instanceof Promise?r.then(Zi):Zi(r)}});function Zi(e){return e.value=Object.freeze(e.value),e}const Ci=en("$ZodCustom",(e,t)=>{_r.init(e,t),Or.init(e,t),e._zod.parse=(e,t)=>e,e._zod.check=n=>{const r=n.value,i=t.fn(r);if(i instanceof Promise)return i.then(t=>Fi(t,n,r,e));Fi(i,n,r,e)}});function Fi(e,t,n,r){if(!e){const e={code:"custom",input:n,inst:r,path:[...r._zod.def.path??[]],continue:!r._zod.def.abort};r._zod.def.params&&(e.params=r._zod.def.params),t.issues.push(En(e))}}class Di{constructor(){this._map=new WeakMap,this._idmap=new Map}add(e,...t){const n=t[0];if(this._map.set(e,n),n&&"object"==typeof n&&"id"in n){if(this._idmap.has(n.id))throw new Error(`ID ${n.id} already exists in the registry`);this._idmap.set(n.id,e)}return this}clear(){return this._map=new WeakMap,this._idmap=new Map,this}remove(e){const t=this._map.get(e);return t&&"object"==typeof t&&"id"in t&&this._idmap.delete(t.id),this._map.delete(e),this}get(e){const t=e._zod.parent;if(t){const n={...this.get(t)??{}};delete n.id;const r={...n,...this._map.get(e)};return Object.keys(r).length?r:void 0}return this._map.get(e)}has(e){return this._map.has(e)}}function Bi(){return new Di}const Ui=Bi();function Ri(e,t){return new e({type:"string",format:"guid",check:"string_format",abort:!1,...bn(t)})}function Mi(e,t){return new yr({check:"max_length",...bn(t),maximum:e})}function qi(e,t){return new wr({check:"min_length",...bn(t),minimum:e})}function Li(e,t){return new vr({check:"length_equals",...bn(t),length:e})}function Wi(e){return new Ar({check:"overwrite",tx:e})}function Ji(e){const t=function(e,t){const n=new _r({check:"custom",...bn(t)});return n._zod.check=e,n}(n=>(n.addIssue=e=>{if("string"==typeof e)n.issues.push(En(e,n.value,t._zod.def));else{const r=e;r.fatal&&(r.continue=!1),r.code??(r.code="custom"),r.input??(r.input=n.value),r.inst??(r.inst=t),r.continue??(r.continue=!t._zod.def.abort),n.issues.push(En(r))}},e(n.value,n)));return t}const Gi=en("ZodISODateTime",(e,t)=>{Wr.init(e,t),wo.init(e,t)});function Hi(e){return function(e,t){return new e({type:"string",format:"datetime",check:"string_format",offset:!1,local:!1,precision:null,...bn(t)})}(Gi,e)}const Vi=en("ZodISODate",(e,t)=>{Jr.init(e,t),wo.init(e,t)});function Ki(e){return function(e,t){return new e({type:"string",format:"date",check:"string_format",...bn(t)})}(Vi,e)}const Xi=en("ZodISOTime",(e,t)=>{Gr.init(e,t),wo.init(e,t)});function Yi(e){return function(e,t){return new e({type:"string",format:"time",check:"string_format",precision:null,...bn(t)})}(Xi,e)}const Qi=en("ZodISODuration",(e,t)=>{Hr.init(e,t),wo.init(e,t)});function eo(e){return function(e,t){return new e({type:"string",format:"duration",check:"string_format",...bn(t)})}(Qi,e)}const to=en("ZodError",(e,t)=>{On.init(e,t),e.name="ZodError",Object.defineProperties(e,{format:{value:t=>function(e,t=e=>e.message){const n={_errors:[]},r=e=>{for(const i of e.issues)if("invalid_union"===i.code&&i.errors.length)i.errors.map(e=>r({issues:e}));else if("invalid_key"===i.code)r({issues:i.issues});else if("invalid_element"===i.code)r({issues:i.issues});else if(0===i.path.length)n._errors.push(t(i));else{let e=n,r=0;for(;r<i.path.length;){const n=i.path[r];r===i.path.length-1?(e[n]=e[n]||{_errors:[]},e[n]._errors.push(t(i))):e[n]=e[n]||{_errors:[]},e=e[n],r++}}};return r(e),n}(e,t)},flatten:{value:t=>function(e,t=e=>e.message){const n={},r=[];for(const i of e.issues)i.path.length>0?(n[i.path[0]]=n[i.path[0]]||[],n[i.path[0]].push(t(i))):r.push(t(i));return{formErrors:r,fieldErrors:n}}(e,t)},addIssue:{value:t=>{e.issues.push(t),e.message=JSON.stringify(e.issues,sn,2)}},addIssues:{value:t=>{e.issues.push(...t),e.message=JSON.stringify(e.issues,sn,2)}},isEmpty:{get:()=>0===e.issues.length}})},{Parent:Error}),no=Nn(to),ro=Tn(to),io=Zn(to),oo=Fn(to),so=Bn(to),ao=Un(to),co=Rn(to),lo=Mn(to),uo=qn(to),fo=Ln(to),po=Wn(to),go=Jn(to),mo=en("ZodType",(e,t)=>(Or.init(e,t),e.def=t,e.type=t.type,Object.defineProperty(e,"_def",{value:t}),e.check=(...n)=>e.clone(pn(t,{checks:[...t.checks??[],...n.map(e=>"function"==typeof e?{_zod:{check:e,def:{check:"custom"},onattach:[]}}:e)]})),e.clone=(t,n)=>Sn(e,t,n),e.brand=()=>e,e.register=(t,n)=>(t.add(e,n),e),e.parse=(t,n)=>no(e,t,n,{callee:e.parse}),e.safeParse=(t,n)=>io(e,t,n),e.parseAsync=async(t,n)=>ro(e,t,n,{callee:e.parseAsync}),e.safeParseAsync=async(t,n)=>oo(e,t,n),e.spa=e.safeParseAsync,e.encode=(t,n)=>so(e,t,n),e.decode=(t,n)=>ao(e,t,n),e.encodeAsync=async(t,n)=>co(e,t,n),e.decodeAsync=async(t,n)=>lo(e,t,n),e.safeEncode=(t,n)=>uo(e,t,n),e.safeDecode=(t,n)=>fo(e,t,n),e.safeEncodeAsync=async(t,n)=>po(e,t,n),e.safeDecodeAsync=async(t,n)=>go(e,t,n),e.refine=(t,n)=>e.check(function(e,t={}){return function(e,t,n){return new e({type:"custom",check:"custom",fn:t,...bn(n)})}(hs,e,t)}(t,n)),e.superRefine=t=>e.check(Ji(t)),e.overwrite=t=>e.check(Wi(t)),e.optional=()=>ss(e),e.nullable=()=>cs(e),e.nullish=()=>ss(cs(e)),e.nonoptional=t=>function(e,t){return new ds({type:"nonoptional",innerType:e,...bn(t)})}(e,t),e.array=()=>Jo(e),e.or=t=>Ko([e,t]),e.and=t=>new Xo({type:"intersection",left:e,right:t}),e.transform=t=>gs(e,new is({type:"transform",transform:t})),e.default=t=>{return n=t,new ls({type:"default",innerType:e,get defaultValue(){return"function"==typeof n?n():wn(n)}});var n},e.prefault=t=>{return n=t,new us({type:"prefault",innerType:e,get defaultValue(){return"function"==typeof n?n():wn(n)}});var n},e.catch=t=>{return new fs({type:"catch",innerType:e,catchValue:"function"==typeof(n=t)?n:()=>n});var n},e.pipe=t=>gs(e,t),e.readonly=()=>new ms({type:"readonly",innerType:e}),e.describe=t=>{const n=e.clone();return Ui.add(n,{description:t}),n},Object.defineProperty(e,"description",{get:()=>Ui.get(e)?.description,configurable:!0}),e.meta=(...t)=>{if(0===t.length)return Ui.get(e);const n=e.clone();return Ui.add(n,t[0]),n},e.isOptional=()=>e.safeParse(void 0).success,e.isNullable=()=>e.safeParse(null).success,e)),ho=en("_ZodString",(e,t)=>{Pr.init(e,t),mo.init(e,t);const n=e._zod.bag;e.format=n.format??null,e.minLength=n.minimum??null,e.maxLength=n.maximum??null,e.regex=(...t)=>e.check(function(e,t){return new Sr({check:"string_format",format:"regex",...bn(t),pattern:e})}(...t)),e.includes=(...t)=>e.check(function(e,t){return new zr({check:"string_format",format:"includes",...bn(t),includes:e})}(...t)),e.startsWith=(...t)=>e.check(function(e,t){return new jr({check:"string_format",format:"starts_with",...bn(t),prefix:e})}(...t)),e.endsWith=(...t)=>e.check(function(e,t){return new xr({check:"string_format",format:"ends_with",...bn(t),suffix:e})}(...t)),e.min=(...t)=>e.check(qi(...t)),e.max=(...t)=>e.check(Mi(...t)),e.length=(...t)=>e.check(Li(...t)),e.nonempty=(...t)=>e.check(qi(1,...t)),e.lowercase=t=>e.check(function(e){return new br({check:"string_format",format:"lowercase",...bn(e)})}(t)),e.uppercase=t=>e.check(function(e){return new $r({check:"string_format",format:"uppercase",...bn(e)})}(t)),e.trim=()=>e.check(Wi(e=>e.trim())),e.normalize=(...t)=>e.check(function(e){return Wi(t=>t.normalize(e))}(...t)),e.toLowerCase=()=>e.check(Wi(e=>e.toLowerCase())),e.toUpperCase=()=>e.check(Wi(e=>e.toUpperCase()))}),_o=en("ZodString",(e,t)=>{Pr.init(e,t),ho.init(e,t),e.email=t=>e.check(function(e,t){return new e({type:"string",format:"email",check:"string_format",abort:!1,...bn(t)})}(vo,t)),e.url=t=>e.check(function(e,t){return new e({type:"string",format:"url",check:"string_format",abort:!1,...bn(t)})}(bo,t)),e.jwt=t=>e.check(function(e,t){return new e({type:"string",format:"jwt",check:"string_format",abort:!1,...bn(t)})}(Do,t)),e.emoji=t=>e.check(function(e,t){return new e({type:"string",format:"emoji",check:"string_format",abort:!1,...bn(t)})}($o,t)),e.guid=t=>e.check(Ri(ko,t)),e.uuid=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,...bn(t)})}(So,t)),e.uuidv4=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v4",...bn(t)})}(So,t)),e.uuidv6=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v6",...bn(t)})}(So,t)),e.uuidv7=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v7",...bn(t)})}(So,t)),e.nanoid=t=>e.check(function(e,t){return new e({type:"string",format:"nanoid",check:"string_format",abort:!1,...bn(t)})}(zo,t)),e.guid=t=>e.check(Ri(ko,t)),e.cuid=t=>e.check(function(e,t){return new e({type:"string",format:"cuid",check:"string_format",abort:!1,...bn(t)})}(jo,t)),e.cuid2=t=>e.check(function(e,t){return new e({type:"string",format:"cuid2",check:"string_format",abort:!1,...bn(t)})}(xo,t)),e.ulid=t=>e.check(function(e,t){return new e({type:"string",format:"ulid",check:"string_format",abort:!1,...bn(t)})}(Ao,t)),e.base64=t=>e.check(function(e,t){return new e({type:"string",format:"base64",check:"string_format",abort:!1,...bn(t)})}(Zo,t)),e.base64url=t=>e.check(function(e,t){return new e({type:"string",format:"base64url",check:"string_format",abort:!1,...bn(t)})}(Co,t)),e.xid=t=>e.check(function(e,t){return new e({type:"string",format:"xid",check:"string_format",abort:!1,...bn(t)})}(Eo,t)),e.ksuid=t=>e.check(function(e,t){return new e({type:"string",format:"ksuid",check:"string_format",abort:!1,...bn(t)})}(Io,t)),e.ipv4=t=>e.check(function(e,t){return new e({type:"string",format:"ipv4",check:"string_format",abort:!1,...bn(t)})}(Oo,t)),e.ipv6=t=>e.check(function(e,t){return new e({type:"string",format:"ipv6",check:"string_format",abort:!1,...bn(t)})}(Po,t)),e.cidrv4=t=>e.check(function(e,t){return new e({type:"string",format:"cidrv4",check:"string_format",abort:!1,...bn(t)})}(No,t)),e.cidrv6=t=>e.check(function(e,t){return new e({type:"string",format:"cidrv6",check:"string_format",abort:!1,...bn(t)})}(To,t)),e.e164=t=>e.check(function(e,t){return new e({type:"string",format:"e164",check:"string_format",abort:!1,...bn(t)})}(Fo,t)),e.datetime=t=>e.check(Hi(t)),e.date=t=>e.check(Ki(t)),e.time=t=>e.check(Yi(t)),e.duration=t=>e.check(eo(t))});function yo(e){return function(e,t){return new e({type:"string",...bn(t)})}(_o,e)}const wo=en("ZodStringFormat",(e,t)=>{Nr.init(e,t),ho.init(e,t)}),vo=en("ZodEmail",(e,t)=>{Cr.init(e,t),wo.init(e,t)}),ko=en("ZodGUID",(e,t)=>{Tr.init(e,t),wo.init(e,t)}),So=en("ZodUUID",(e,t)=>{Zr.init(e,t),wo.init(e,t)}),bo=en("ZodURL",(e,t)=>{Fr.init(e,t),wo.init(e,t)}),$o=en("ZodEmoji",(e,t)=>{Dr.init(e,t),wo.init(e,t)}),zo=en("ZodNanoID",(e,t)=>{Br.init(e,t),wo.init(e,t)}),jo=en("ZodCUID",(e,t)=>{Ur.init(e,t),wo.init(e,t)}),xo=en("ZodCUID2",(e,t)=>{Rr.init(e,t),wo.init(e,t)}),Ao=en("ZodULID",(e,t)=>{Mr.init(e,t),wo.init(e,t)}),Eo=en("ZodXID",(e,t)=>{qr.init(e,t),wo.init(e,t)}),Io=en("ZodKSUID",(e,t)=>{Lr.init(e,t),wo.init(e,t)}),Oo=en("ZodIPv4",(e,t)=>{Vr.init(e,t),wo.init(e,t)}),Po=en("ZodIPv6",(e,t)=>{Kr.init(e,t),wo.init(e,t)}),No=en("ZodCIDRv4",(e,t)=>{Xr.init(e,t),wo.init(e,t)}),To=en("ZodCIDRv6",(e,t)=>{Yr.init(e,t),wo.init(e,t)}),Zo=en("ZodBase64",(e,t)=>{ei.init(e,t),wo.init(e,t)}),Co=en("ZodBase64URL",(e,t)=>{ti.init(e,t),wo.init(e,t)}),Fo=en("ZodE164",(e,t)=>{ni.init(e,t),wo.init(e,t)}),Do=en("ZodJWT",(e,t)=>{ri.init(e,t),wo.init(e,t)}),Bo=en("ZodBoolean",(e,t)=>{ii.init(e,t),mo.init(e,t)});function Uo(e){return function(e,t){return new e({type:"boolean",...bn(t)})}(Bo,e)}const Ro=en("ZodUnknown",(e,t)=>{oi.init(e,t),mo.init(e,t)});function Mo(){return new Ro({type:"unknown"})}const qo=en("ZodNever",(e,t)=>{si.init(e,t),mo.init(e,t)});function Lo(e){return function(e,t){return new e({type:"never",...bn(t)})}(qo,e)}const Wo=en("ZodArray",(e,t)=>{ci.init(e,t),mo.init(e,t),e.element=t.element,e.min=(t,n)=>e.check(qi(t,n)),e.nonempty=t=>e.check(qi(1,t)),e.max=(t,n)=>e.check(Mi(t,n)),e.length=(t,n)=>e.check(Li(t,n)),e.unwrap=()=>e.element});function Jo(e,t){return function(e,t,n){return new e({type:"array",element:t,...bn(n)})}(Wo,e,t)}const Go=en("ZodObject",(e,t)=>{pi.init(e,t),mo.init(e,t),dn(e,"shape",()=>t.shape),e.keyof=()=>ts(Object.keys(e._zod.def.shape)),e.catchall=t=>e.clone({...e._zod.def,catchall:t}),e.passthrough=()=>e.clone({...e._zod.def,catchall:Mo()}),e.loose=()=>e.clone({...e._zod.def,catchall:Mo()}),e.strict=()=>e.clone({...e._zod.def,catchall:Lo()}),e.strip=()=>e.clone({...e._zod.def,catchall:void 0}),e.extend=t=>function(e,t){if(!yn(t))throw new Error("Invalid input to extend: expected a plain object");const n=e._zod.def.checks;if(n&&n.length>0)throw new Error("Object schemas containing refinements cannot be extended. Use `.safeExtend()` instead.");const r=pn(e._zod.def,{get shape(){const n={...e._zod.def.shape,...t};return fn(this,"shape",n),n},checks:[]});return Sn(e,r)}(e,t),e.safeExtend=t=>function(e,t){if(!yn(t))throw new Error("Invalid input to safeExtend: expected a plain object");const n={...e._zod.def,get shape(){const n={...e._zod.def.shape,...t};return fn(this,"shape",n),n},checks:e._zod.def.checks};return Sn(e,n)}(e,t),e.merge=t=>function(e,t){const n=pn(e._zod.def,{get shape(){const n={...e._zod.def.shape,...t._zod.def.shape};return fn(this,"shape",n),n},get catchall(){return t._zod.def.catchall},checks:[]});return Sn(e,n)}(e,t),e.pick=t=>function(e,t){const n=e._zod.def;return Sn(e,pn(e._zod.def,{get shape(){const e={};for(const r in t){if(!(r in n.shape))throw new Error(`Unrecognized key: "${r}"`);t[r]&&(e[r]=n.shape[r])}return fn(this,"shape",e),e},checks:[]}))}(e,t),e.omit=t=>function(e,t){const n=e._zod.def,r=pn(e._zod.def,{get shape(){const r={...e._zod.def.shape};for(const e in t){if(!(e in n.shape))throw new Error(`Unrecognized key: "${e}"`);t[e]&&delete r[e]}return fn(this,"shape",r),r},checks:[]});return Sn(e,r)}(e,t),e.partial=(...t)=>function(e,t,n){const r=pn(t._zod.def,{get shape(){const r=t._zod.def.shape,i={...r};if(n)for(const t in n){if(!(t in r))throw new Error(`Unrecognized key: "${t}"`);n[t]&&(i[t]=e?new e({type:"optional",innerType:r[t]}):r[t])}else for(const t in r)i[t]=e?new e({type:"optional",innerType:r[t]}):r[t];return fn(this,"shape",i),i},checks:[]});return Sn(t,r)}(os,e,t[0]),e.required=(...t)=>function(e,t,n){const r=pn(t._zod.def,{get shape(){const r=t._zod.def.shape,i={...r};if(n)for(const t in n){if(!(t in i))throw new Error(`Unrecognized key: "${t}"`);n[t]&&(i[t]=new e({type:"nonoptional",innerType:r[t]}))}else for(const t in r)i[t]=new e({type:"nonoptional",innerType:r[t]});return fn(this,"shape",i),i},checks:[]});return Sn(t,r)}(ds,e,t[0])});function Ho(e,t){const n={type:"object",shape:e??{},...bn(t)};return new Go(n)}const Vo=en("ZodUnion",(e,t)=>{mi.init(e,t),mo.init(e,t),e.options=t.options});function Ko(e,t){return new Vo({type:"union",options:e,...bn(t)})}const Xo=en("ZodIntersection",(e,t)=>{hi.init(e,t),mo.init(e,t)});const Yo=en("ZodRecord",(e,t)=>{wi.init(e,t),mo.init(e,t),e.keyType=t.keyType,e.valueType=t.valueType});function Qo(e,t,n){return new Yo({type:"record",keyType:e,valueType:t,...bn(n)})}const es=en("ZodEnum",(e,t)=>{vi.init(e,t),mo.init(e,t),e.enum=t.entries,e.options=Object.values(t.entries);const n=new Set(Object.keys(t.entries));e.extract=(e,r)=>{const i={};for(const r of e){if(!n.has(r))throw new Error(`Key ${r} not found in enum`);i[r]=t.entries[r]}return new es({...t,checks:[],...bn(r),entries:i})},e.exclude=(e,r)=>{const i={...t.entries};for(const t of e){if(!n.has(t))throw new Error(`Key ${t} not found in enum`);delete i[t]}return new es({...t,checks:[],...bn(r),entries:i})}});function ts(e,t){const n=Array.isArray(e)?Object.fromEntries(e.map(e=>[e,e])):e;return new es({type:"enum",entries:n,...bn(t)})}const ns=en("ZodLiteral",(e,t)=>{ki.init(e,t),mo.init(e,t),e.values=new Set(t.values),Object.defineProperty(e,"value",{get(){if(t.values.length>1)throw new Error("This schema contains multiple valid literal values. Use `.values` instead.");return t.values[0]}})});function rs(e,t){return new ns({type:"literal",values:Array.isArray(e)?e:[e],...bn(t)})}const is=en("ZodTransform",(e,t)=>{Si.init(e,t),mo.init(e,t),e._zod.parse=(n,r)=>{if("backward"===r.direction)throw new nn(e.constructor.name);n.addIssue=r=>{if("string"==typeof r)n.issues.push(En(r,n.value,t));else{const t=r;t.fatal&&(t.continue=!1),t.code??(t.code="custom"),t.input??(t.input=n.value),t.inst??(t.inst=e),n.issues.push(En(t))}};const i=t.transform(n.value,n);return i instanceof Promise?i.then(e=>(n.value=e,n)):(n.value=i,n)}});const os=en("ZodOptional",(e,t)=>{$i.init(e,t),mo.init(e,t),e.unwrap=()=>e._zod.def.innerType});function ss(e){return new os({type:"optional",innerType:e})}const as=en("ZodNullable",(e,t)=>{zi.init(e,t),mo.init(e,t),e.unwrap=()=>e._zod.def.innerType});function cs(e){return new as({type:"nullable",innerType:e})}const ls=en("ZodDefault",(e,t)=>{ji.init(e,t),mo.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeDefault=e.unwrap});const us=en("ZodPrefault",(e,t)=>{Ai.init(e,t),mo.init(e,t),e.unwrap=()=>e._zod.def.innerType});const ds=en("ZodNonOptional",(e,t)=>{Ei.init(e,t),mo.init(e,t),e.unwrap=()=>e._zod.def.innerType});const fs=en("ZodCatch",(e,t)=>{Oi.init(e,t),mo.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeCatch=e.unwrap});const ps=en("ZodPipe",(e,t)=>{Pi.init(e,t),mo.init(e,t),e.in=t.in,e.out=t.out});function gs(e,t){return new ps({type:"pipe",in:e,out:t})}const ms=en("ZodReadonly",(e,t)=>{Ti.init(e,t),mo.init(e,t),e.unwrap=()=>e._zod.def.innerType});const hs=en("ZodCustom",(e,t)=>{Ci.init(e,t),mo.init(e,t)});const _s="directus:extension",ys=Ho({app:yo(),api:yo()}),ws=Ho({request:ss(Ho({urls:Jo(yo()),methods:Jo(Ko([rs("GET"),rs("POST"),rs("PATCH"),rs("PUT"),rs("DELETE")]))})),log:ss(Ho({})),sleep:ss(Ho({}))}),vs=ss(Ho({enabled:Uo(),requestedScopes:ws})),ks=Ko([Ho({type:ts(Yt),name:yo(),source:yo()}),Ho({type:ts(Xt),name:yo(),source:yo()}),Ho({type:ts(Qt),name:yo(),source:ys})]),Ss=Ho({host:yo(),hidden:Uo().optional()}),bs=Ho({type:ts(Xt),path:yo(),source:yo()}),$s=Ho({type:ts(Yt),path:yo(),source:yo(),sandbox:vs}),zs=Ho({type:ts(Qt),path:ys,source:ys,sandbox:vs}),js=Ho({type:rs("bundle"),partial:Uo().optional(),path:ys,entries:Jo(ks)});Jo(ks);const xs=Ss.and(Ko([bs,$s,zs,js]));Ho({name:yo(),version:yo(),type:Ko([rs("module"),rs("commonjs")]).optional(),description:yo().optional(),icon:yo().optional(),dependencies:Qo(yo(),yo()).optional(),devDependencies:Qo(yo(),yo()).optional(),[_s]:xs});function As(e){return Object.entries(e).filter(([,e])=>Ke(e)&&He(e.prefix_strategy)).map(([e])=>e)}async function Es(e,t,n,r,i){if(n&&n!==r)for(const o of t)try{const t=await e("directus_files").count({c:"*"}).where("storage",o).whereRaw("filename_disk LIKE ?",[`${n}/%`]).first(),s=Number(t?.c??0);s>=100&&i.warn(`[storage-manager] Folder path sync on ${o}: relocating ${s} files (“${n}” → “${r||"(root)"}”) — this may take a while`);const{moved:a,failed:c}=await se(e,o,n,r,i);(a||c)&&i.info(`[storage-manager] Folder path sync on ${o}: "${n}" → "${r||"(root)"}" (moved=${a}, failed=${c})`)}catch(e){i.error(`[storage-manager] Folder path sync failed for ${o}: ${e?.message}`)}}async function Is(e,t,n){const r={},i={},o=await t("directus_folders").select("id","parent").where("id",e).first(),s=o?.parent?String(o.parent):null;for(const o of(a=n,Object.entries(a).filter(([,e])=>Ke(e)).map(([e])=>e))){const a=n[o];let c=null,l="";He(a.prefix_strategy)?(c=await Ye(t,e),l=s&&await Ye(t,s)||""):Ve(a.prefix_strategy)&&(c=await Qe(t,e),l=s&&await Qe(t,s)||""),c&&(r[o]=c,i[o]=l)}var a;return{folderPaths:r,parentPaths:i}}async function Os(e,t,n){const r=await n("directus_folders").select("id","name","parent").where("id",e).first();if(!r)return null;const i=String(r.name);if(i===t)return null;const o=r.parent?String(r.parent):null,s=new Set([e,...await Re(n,o,i),...await Re(n,o,t)]),a={};for(const e of s){const t=await Ye(n,e);t&&(a[e]=t)}return a}async function Ps(e,t){const n=await t("directus_folders").select("id","name","parent").where("id",e).first();if(!n)return null;const r=String(n.name),i=n.parent?String(n.parent):null,o=(await Re(t,i,r)).filter(t=>t!==e),s={};for(const e of o){const n=await Ye(t,e);n&&(s[e]=n)}return{parent:i,name:r,siblingOldPaths:s}}async function Ns(e,t,n,r,i){const o=As(r);if(o.length)for(const[e,r]of Object.entries(t)){const t=await Ye(n,e);t&&r&&t!==r&&await Es(n,o,r,t,i)}}async function Ts(e,t,n,r){const i=As(n);if(i.length)for(const[n,o]of Object.entries(e)){const e=await Ye(t,n);e&&o&&e!==o&&await Es(t,i,o,e,r)}}async function Zs(e,t,n,r,i,o){for(const[e,s]of Object.entries(t)){const t=i[e];if(!t||!Ke(t))continue;const a=n[e]??"";await Es(r,[e],s,a,o)}}async function Cs(e){const t=await e.database("directus_files").select("id","storage","filename_disk","folder","type","uploaded_on").where("id",e.fileId).first();if(!t?.filename_disk)return;const n=String(t.storage??(r=e.env,String(r.STORAGE_LOCATIONS??"local").split(",").map(e=>e.trim()).filter(Boolean)[0]??"local"));var r;const i=Ce(await Te(e.database),n);if(!Ke(i))return;const o=await tt(i,t,e.database);if(!o)return;const s=String(t.filename_disk);if(s.startsWith(`${o}/`)||s===o)return;const a=(await ne(e.database,n,[e.fileId],o,e.logger,e.env)).results[0];"failed"===a?.status&&e.logger.warn(`[storage-manager] Upload mirror failed for ${e.fileId}: ${a.error||"unknown error"}`)}const Fs=new Set(["storage-manager-file-with-storage","storage-manager-image-with-storage","storage-manager-files-with-storage","file","file-image","files"]);async function Ds(e){const t=await e("directus_fields").select("collection","field","interface","options"),n=new Map;for(const e of t||[]){const t=String(e.interface||"");if(!Fs.has(t))continue;let r={};try{r="string"==typeof e.options?JSON.parse(e.options):e.options&&"object"==typeof e.options?e.options:{}}catch{r={}}const i=r.onDeselect,o=r.onItemDelete;n.set(`${e.collection}.${e.field}`,{onDeselect:"keep"===i||"ask"===i||"delete_if_unreferenced"===i?i:null,onItemDelete:"keep"===o||"delete_if_unreferenced"===o?o:null})}return n}function Bs(e){if(null==e)return[];if("string"==typeof e||"number"==typeof e){const t=wt(String(e));return t?[t]:[]}if(Array.isArray(e)){const t=[];for(const n of e)t.push(...Bs(n));return t}if("object"==typeof e){const t=e;if(null!=t.id)return Bs(t.id);if(null!=t.directus_files_id)return Bs(t.directus_files_id);for(const e of Object.values(t))if(e&&"object"==typeof e){const t=Bs(e);if(t.length)return t}}return[]}const Us=[{name:"storage-manager-hook",config:({filter:e,action:t},{database:n,env:r,services:i,getSchema:o,logger:s})=>{t("server.start",async()=>{await Fe(n,i,o,s)}),function({filter:e,action:t},n){const{database:r,services:i,getSchema:o,logger:s}=n,a=new Map,c=new Map;function l(e,t){return`${e}::${[...t].map(String).sort().join(",")}`}e("items.delete",async(e,t)=>{try{const n=String(t?.collection||"");if(!n||"directus_files"===n)return e;const i=Oe((await Te(r)).lifecycle??Ie),c=await Ds(r),u=await o(),d=Array.isArray(u?.relations)?u.relations:[],f=It(u),p=f.filter(e=>e.collection===n),g=[];for(const e of f){if(e.collection===n)continue;const t=d.find(t=>String(t?.collection)===e.collection&&String(t?.related_collection)===n&&String(t?.field)!==e.field);t?.field&&g.push({table:e.collection,fileField:e.field,parentField:String(t.field)})}if(!p.length&&!g.length)return e;const m=(Array.isArray(e)?e:[e]).map(String).filter(Boolean);if(!m.length)return e;const h=u.collections?.[n]?.primary||"id",_=new Set;if(p.length){const e=await r(n).select("*").whereIn(h,m);for(const t of e)for(const e of p){const r=c.get(`${n}.${e.field}`);if("delete_if_unreferenced"===(r?.onItemDelete??i.on_item_delete))for(const n of Bs(t[e.field]))_.add(n)}}if("delete_if_unreferenced"===i.on_item_delete)for(const e of g)try{const t=await r(e.table).select(e.fileField).whereIn(e.parentField,m).whereNotNull(e.fileField);for(const n of t)for(const t of Bs(n[e.fileField]))_.add(t)}catch(t){s.warn(`[storage-manager] lifecycle junction capture ${e.table}: ${t?.message||t}`)}_.size&&a.set(l(n,m),Array.from(_))}catch(e){s.warn(`[storage-manager] lifecycle items.delete capture failed: ${e?.message||e}`)}return e}),t("items.delete",async e=>{try{const t=l(String(e?.collection||""),(e.keys??e.payload??(e.key?[e.key]:[])).map(String)),n=a.get(t);if(a.delete(t),!n?.length)return;const c=Oe((await Te(r)).lifecycle??Ie),u=await o();await Dt(r,u,i,null,n,{scanTextFields:c.scan_text_fields,logger:s})}catch(e){s.warn(`[storage-manager] lifecycle items.delete cleanup failed: ${e?.message||e}`)}}),e("items.update",async(e,t)=>{try{const n=String(t?.collection||"");if(!n||"directus_files"===n)return e;if(!e||"object"!=typeof e)return e;const i=Oe((await Te(r)).lifecycle??Ie),s=await Ds(r),a=await o(),u=It(a).filter(e=>e.collection===n);if(!u.length)return e;const d=u.filter(t=>Object.prototype.hasOwnProperty.call(e,t.field));if(!d.length)return e;const f=(t.keys??[]).map(String).filter(Boolean);if(!f.length)return e;const p=a.collections?.[n]?.primary||"id",g=await r(n).select([p,...d.map(e=>e.field)]).whereIn(p,f),m=new Set;for(const t of g)for(const r of d){const o=s.get(`${n}.${r.field}`);if("delete_if_unreferenced"!==(o?.onDeselect??i.on_deselect))continue;const a=e[r.field],c=Bs(t[r.field]),l=new Set(Bs(a));for(const e of c)l.has(e)||m.add(e)}m.size&&c.set(l(n,f),Array.from(m))}catch(e){s.warn(`[storage-manager] lifecycle items.update capture failed: ${e?.message||e}`)}return e}),t("items.update",async e=>{try{const t=l(String(e?.collection||""),(e.keys??(e.key?[e.key]:[])).map(String)),n=c.get(t);if(c.delete(t),!n?.length)return;const a=Oe((await Te(r)).lifecycle??Ie),u=await o();await Dt(r,u,i,null,n,{scanTextFields:a.scan_text_fields,logger:s})}catch(e){s.warn(`[storage-manager] lifecycle items.update cleanup failed: ${e?.message||e}`)}})}({filter:e,action:t},{database:n,services:i,getSchema:o,logger:s}),e("settings.update",e=>(C in e&&Ne(),e)),e("files.create",async e=>{try{const t=String(r.STORAGE_LOCATIONS??"local").split(",").map(e=>e.trim()).filter(Boolean),i=String(e.storage??t[0]??"local"),o=Ce(await Te(n),i);if(!Ke(o))return e;const s=await tt(o,e,n);if(!s)return e;const a=String(e.filename_disk??"");a.startsWith(`${s}/`)||(e.filename_disk=`${s}/${a}`)}catch(e){s.warn(`[storage-manager] Prefix injection failed: ${e?.message}`)}return e}),t("files.upload",async e=>{if(null!=e.key)try{await Cs({database:n,env:r,fileId:String(e.key),logger:s})}catch(e){s.warn(`[storage-manager] Upload mirror failed: ${e?.message}`)}}),t("folders.create",async e=>{try{const t=e.keys??(e.key?[e.key]:[]);for(const e of t)await Le(e,n,s)}catch(e){s.warn(`[storage-manager] Folder create claim update failed: ${e?.message}`)}});const a=new Map,c=new Map;e("folders.update",async(e,t)=>{if(!e.name)return e;try{const r=await Te(n),i=Object.values(r.locations).some(e=>Ke(e)&&He(e.prefix_strategy)),o=t.keys??(t.key?[t.key]:[]),s=String(e.name);for(const e of o){const t=await n("directus_folders").select("name","parent").where("id",e).first();if(t&&c.set(e,{oldName:String(t.name),newName:s,parent:t.parent?String(t.parent):null}),!i)continue;const r=await Os(e,s,n);r&&Object.keys(r).length&&a.set(e,r)}}catch(e){s.warn(`[storage-manager] Folder rename pre-capture failed: ${e?.message}`)}return e}),t("folders.update",async e=>{if(e.payload?.name)try{const t=await Te(n),r=e.keys??(e.key?[e.key]:[]);for(const e of r){const r=c.get(e);c.delete(e),r&&await We(e,r.oldName,r.newName,r.parent,n,s);const i=a.get(e);a.delete(e),i&&await Ns(0,i,n,t.locations,s)}}catch(e){s.error(`[storage-manager] Folder rename sync error: ${e?.message}`)}});const l=new Map,u=new Map,d=new Map;e("folders.delete",async e=>{try{const t=await Te(n),r=Object.values(t.locations).some(e=>Ke(e)),i=Object.values(t.locations).some(e=>Ke(e)&&He(e.prefix_strategy));for(const o of e){const e=await Ge(o,n);if(e&&d.set(o,e),!r)continue;const s=await Is(o,n,t.locations);if(Object.keys(s.folderPaths).length&&l.set(o,s),i){const e=await Ps(o,n);e&&Object.keys(e.siblingOldPaths).length&&u.set(o,e.siblingOldPaths)}}}catch(e){s.warn(`[storage-manager] Folder delete pre-capture failed: ${e?.message}`)}return e}),t("folders.delete",async e=>{const t=e.keys??[];try{const e=await Te(n);for(const r of t){const t=d.get(r);d.delete(r),t&&await Je(r,t.parent,t.name,n,s);const i=l.get(r);l.delete(r),i&&await Zs(0,i.folderPaths,i.parentPaths,n,e.locations,s);const o=u.get(r);u.delete(r),o&&await Ts(o,n,e.locations,s)}}catch(e){s.error(`[storage-manager] Folder delete sync error: ${e?.message}`)}});const f=new Map;e("files.delete",async e=>{try{const t=await async function(e,t){const n=(t||[]).map(String).filter(Boolean);if(!n.length)return[];const r=await e("directus_files").select("id","storage","filename_disk").whereIn("id",n),i=[];for(const e of r||[]){const t=String(e?.filename_disk||"").replace(/\\/g,"/").replace(/^\/+/,"");if(!t.includes("/"))continue;const n=String(e?.storage||"").trim();n&&i.push({id:String(e.id),storage:n,filename_disk:t})}return i}(n,e);for(const e of t)f.set(e.id,e)}catch(e){s.warn(`[storage-manager] Nested file delete pre-capture failed: ${e?.message}`)}return e}),t("files.delete",async e=>{const t=(e.keys??[]).map(String),n=[];for(const e of t){const t=f.get(e);t&&(f.delete(e),n.push(t))}if(n.length)try{await async function(e,t){if(!e.length)return;const n=await g();for(const r of e)try{const e=n.location(r.storage);await j(e,r.filename_disk)}catch(e){t?.warn(`[storage-manager] Nested file leftover after delete (${r.storage}/${r.filename_disk}): ${e?.message||e}`)}}(n,s)}catch(e){s.warn(`[storage-manager] Nested file leftover cleanup failed: ${e?.message}`)}})}}],Rs=[{name:"storage-manager-endpoint",config:Vt}],Ms=[{name:"storage-manager-operation",config:Kt}];export{Rs as endpoints,Us as hooks,Ms as operations};
|