directus-extension-storage-manager 1.2.0 → 1.2.2
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/README.md +42 -170
- package/dist/api.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,177 +1,92 @@
|
|
|
1
1
|
# Storage Manager
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Move files between your Directus storages — local disk, S3, Google Cloud, Azure, and more — without losing the file in Directus. The file keeps the same ID. Only where it lives changes.
|
|
4
4
|
|
|
5
|
-
>
|
|
5
|
+
> Before a large move, click **Dry Run**. That shows what would happen without moving anything. Studio always **moves** files (it does not leave a copy behind). Copy exists only as a Flow operation.
|
|
6
6
|
|
|
7
7
|
## Overview
|
|
8
8
|
|
|
9
9
|
<img alt="Storage Manager overview with local, local2, S3, and GCS adapters" src="https://raw.githubusercontent.com/domdus/directus-extension-storage-manager/main/docs/screenshot_storage_manager.png" width="800" />
|
|
10
10
|
|
|
11
|
-
Directus can use several
|
|
11
|
+
Directus can use several storages at once, but it will not move existing files for you. Storage Manager does: browse each storage, upload, find files that are on disk but not in Directus, and move files or whole folders.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
### Your storages
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
The overview shows every storage with file counts, folder counts, and usage. **Browse** opens that storage’s files and folders.
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- See every configured storage location with file counts, folder counts, usage, and root / bucket
|
|
20
|
-
- Per-adapter **Mirror Directus Folders** toggle
|
|
21
|
-
- **Browse** opens that adapter’s files and folders
|
|
17
|
+
Cloud storages often cannot report a full disk quota. In that case the bar shows the size Directus already knows about.
|
|
22
18
|
|
|
23
19
|
### Mirror Directus Folders
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
- **New uploads** land under the matching physical path (folder names)
|
|
28
|
-
- **Rename / delete** of a Directus folder updates physical paths **on this adapter only**
|
|
29
|
-
|
|
30
|
-
A Directus folder is **virtual**: it can contain files from several adapters at once. Example: `Articles` has some files on `local` and some on `s3`. If both have Mirror on, a rename updates `local` and `s3` independently (each only its own objects). If only `local` has Mirror on, `s3` paths stay unchanged.
|
|
31
|
-
|
|
32
|
-
Sibling folders with the same name use `name_<folder-uid>` so paths stay unique. The first folder to claim a plain name keeps it.
|
|
33
|
-
|
|
34
|
-
Mirror does **not** rewrite files that are already on disk. Use **Move to Storage Folder** or **Materialize** for existing files.
|
|
35
|
-
|
|
36
|
-
### Left navigation
|
|
37
|
-
|
|
38
|
-
1. **Storage Manager** (overview)
|
|
39
|
-
2. **Storage adapters** — expandable physical folder trees
|
|
40
|
-
3. **Directus Folders** — virtual folder tree
|
|
41
|
-
4. **Settings**
|
|
42
|
-
|
|
43
|
-
Trees expand down to the current folder / storage path on load and refresh.
|
|
44
|
-
|
|
45
|
-
### Browse UI
|
|
46
|
-
|
|
47
|
-
- Same card / table layouts as the File Library
|
|
48
|
-
- Physical folder cards appear next to files when browsing a storage path
|
|
49
|
-
- File detail opens in-module (back stays in Storage Manager)
|
|
50
|
-
- Search, filter, and layout presets are remembered per browser
|
|
51
|
-
- **Upload** (header **+**, sidebar, empty states) opens a File Library–style **dropzone dialog**
|
|
52
|
-
- Window-level drag-and-drop onto the page still works
|
|
53
|
-
- In Directus Folders view, each file card shows which storage it lives on
|
|
21
|
+
Turn this on for a storage if you want that storage to follow your Directus folder tree:
|
|
54
22
|
|
|
55
|
-
|
|
23
|
+
- New uploads go into matching folders on that storage
|
|
24
|
+
- Renaming or deleting a Directus folder updates folders **on this storage only**
|
|
56
25
|
|
|
57
|
-
|
|
26
|
+
A Directus folder is only a label in Directus. Files inside it can sit on different storages. If `Articles` has files on `local` and on `s3`, and Mirror is on for both, a rename updates both. If Mirror is only on for `local`, the `s3` files stay put.
|
|
58
27
|
|
|
59
|
-
|
|
60
|
-
- Right-click context menu (nav + folder cards):
|
|
61
|
-
- **Rename Folder** — rewrites nested registered files’ paths and moves objects on disk
|
|
62
|
-
- **Move to Folder** — reparent under another storage path
|
|
63
|
-
- **Delete Folder** — File Library–style dialog: move registered content one level up, or delete all content, then remove the folder
|
|
64
|
-
- **Delete** (header) — selected files via core `/files` delete; when storage folders are selected, same Delete Folder dialog as above
|
|
65
|
-
- Upload / drop into a nested path places the file under that folder after create
|
|
28
|
+
Mirror does not rearrange files that are already stored. Use **Move to Storage Folder** or **Materialize** for those.
|
|
66
29
|
|
|
67
|
-
|
|
30
|
+
If two Directus folders share the same name, the second one gets a unique folder name on disk so they do not collide.
|
|
68
31
|
|
|
69
32
|
### Move to Storage Folder
|
|
70
33
|
|
|
71
|
-
|
|
34
|
+
Pick files, folders, or everything on a storage, then choose where they should go.
|
|
72
35
|
|
|
73
|
-
-
|
|
74
|
-
-
|
|
75
|
-
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
78
|
-
- Whole-adapter moves **preserve nested paths**
|
|
79
|
-
- Studio always **moves** (no Copy in the UI)
|
|
36
|
+
- **Dry Run** first: how many files, folders, and possible conflicts
|
|
37
|
+
- Selected folders keep their name (`hello` stays `hello`). If that folder already exists at the destination, contents are merged into it
|
|
38
|
+
- Loose files land in the folder you pick
|
|
39
|
+
- Moving a whole storage keeps the folder structure
|
|
40
|
+
- Empty folders can be included when you move a storage or selected folders
|
|
80
41
|
|
|
81
42
|
<img alt="Move Files progress from local to S3" src="https://raw.githubusercontent.com/domdus/directus-extension-storage-manager/main/docs/screenshot_storage_move_to_gcs.png" width="800" />
|
|
82
43
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
| Situation | What happens |
|
|
86
|
-
| --- | --- |
|
|
87
|
-
| Destination **folder** already exists | Contents are merged into it |
|
|
88
|
-
| Destination **path** already has another `directus_files` row | Incoming file is **skipped** — it stays on the source. Two files are never pointed at the same path |
|
|
89
|
-
| Destination **blob** exists but no other file row owns it | Treated as resume: this file is pointed at the dest path, then the source is removed |
|
|
44
|
+
If the destination already has a **folder** with that name, files are merged into it. If another Directus file already uses that exact path, the incoming file is skipped and stays where it is. Image thumbnails move with the file when possible.
|
|
90
45
|
|
|
91
46
|
### Materialize
|
|
92
47
|
|
|
93
|
-
In **Directus Folders**, turn
|
|
48
|
+
In **Directus Folders**, turn your Directus folder tree into real folders on storage:
|
|
94
49
|
|
|
95
|
-
- **Keep** — each file stays on its current
|
|
96
|
-
- **Merge** — all files move onto one
|
|
97
|
-
- Recursive (include subfolders)
|
|
98
|
-
- Dry run with file / folder / conflict counts
|
|
50
|
+
- **Keep** — each file stays on its current storage. Only the folder path is created there. You can also build folders without moving files.
|
|
51
|
+
- **Merge** — all files move onto one storage, in the same folder layout as Directus.
|
|
99
52
|
|
|
100
|
-
|
|
53
|
+
Include subfolders if you want the whole tree. Dry Run shows counts before you run it. Directus Folders themselves are not changed.
|
|
101
54
|
|
|
102
55
|
<img alt="Materialize Folder drawer with Keep and Merge storage modes" src="https://raw.githubusercontent.com/domdus/directus-extension-storage-manager/main/docs/screenshot_storage_materialize.png" width="800" />
|
|
103
56
|
|
|
104
|
-
###
|
|
57
|
+
### Detect files
|
|
105
58
|
|
|
106
|
-
|
|
59
|
+
Find files that are on a storage but not yet in Directus.
|
|
107
60
|
|
|
108
|
-
-
|
|
109
|
-
-
|
|
110
|
-
- **Detect** / orphan import / orphan delete skip generated thumbnails, dotfiles, and `directus-health-file`
|
|
61
|
+
- At the storage root: **Detect Files on {storage}**
|
|
62
|
+
- Inside a folder: **Detect Files in this Folder**
|
|
111
63
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
- Scan for objects on disk / bucket that are **not** in Directus yet
|
|
115
|
-
- At storage root: **Detect Files on {adapter}**
|
|
116
|
-
- Inside a physical folder: **Detect Files in this Folder** (scan scoped to that path and subfolders)
|
|
117
|
-
- Import creates database rows only — files stay where they are. Image width/height are read so Directus can generate thumbnails
|
|
118
|
-
- Delete selected orphans permanently (thumbnails are never deleted via this path)
|
|
64
|
+
Import adds them to Directus without moving the files. You can also delete leftover files that Directus does not know about (generated thumbnails are left alone).
|
|
119
65
|
|
|
120
66
|
### Settings
|
|
121
67
|
|
|
122
|
-
|
|
123
|
-
- **Export / Import** JSON backup of Mirror Directus Folders settings
|
|
124
|
-
- **Delete** stored `storage_manager` data from `directus_settings` (field is recreated empty on next start if the extension is still installed)
|
|
68
|
+
Check for updates, export or import your Mirror settings, or remove Storage Manager’s saved settings if you uninstall.
|
|
125
69
|
|
|
126
|
-
###
|
|
70
|
+
### Flows
|
|
127
71
|
|
|
128
|
-
|
|
72
|
+
The **Storage Manager** Flow operation can move (or copy) files in automations. Copy leaves a leftover on the old storage — it will show up under Detect.
|
|
129
73
|
|
|
130
74
|
## Getting started
|
|
131
75
|
|
|
132
|
-
1.
|
|
133
|
-
2. As an admin,
|
|
76
|
+
1. Set up more than one storage if you plan to move files (for example `local` and `s3`).
|
|
77
|
+
2. As an admin, go to **Settings → Project Settings → Modules** and enable **Storage Manager**.
|
|
134
78
|
3. Open **Storage Manager** from the left bar.
|
|
135
|
-
4. On the overview, turn on **Mirror Directus Folders**
|
|
136
|
-
5.
|
|
137
|
-
6. Use **
|
|
138
|
-
|
|
139
|
-
Tips:
|
|
140
|
-
|
|
141
|
-
- After a **Copy** (Flow operation only), leftovers on the old storage can show up under **Detect** — that is expected.
|
|
142
|
-
- Cloud storages often cannot report a full disk quota; the UI then shows Directus file totals only.
|
|
143
|
-
- Virtual folders can span multiple storages; Mirror is always per-adapter.
|
|
144
|
-
- Same-name sibling Directus folders use `name_<folder-uid>` on disk so paths stay unique.
|
|
145
|
-
|
|
146
|
-
## Readable URLs for paths with spaces
|
|
147
|
-
|
|
148
|
-
Disk and the database keep real spaces. Studio routes encode spaces as `_` and existing underscores as `__` so URLs stay readable and reversible.
|
|
149
|
-
|
|
150
|
-
| On disk / in DB | In the Studio URL |
|
|
151
|
-
| --- | --- |
|
|
152
|
-
| `My Test Folder` | `/storage-manager/storage/local/path/My_Test_Folder` |
|
|
153
|
-
| `already_underscored` | `…/already__underscored` |
|
|
154
|
-
|
|
155
|
-
Legacy `%20` segments still decode correctly.
|
|
79
|
+
4. On the overview, turn on **Mirror Directus Folders** for any storage that should follow your Directus folders.
|
|
80
|
+
5. Browse a storage (or **Directus Folders**) and move or materialize as needed.
|
|
81
|
+
6. Use **Dry Run**, then **Move**.
|
|
156
82
|
|
|
157
|
-
##
|
|
158
|
-
|
|
159
|
-
Uses standard Directus storage environment variables — no extension-specific env vars:
|
|
160
|
-
|
|
161
|
-
```bash
|
|
162
|
-
STORAGE_LOCATIONS="local,s3"
|
|
163
|
-
STORAGE_LOCAL_DRIVER="local"
|
|
164
|
-
STORAGE_LOCAL_ROOT="./uploads"
|
|
165
|
-
STORAGE_S3_DRIVER="s3"
|
|
166
|
-
STORAGE_S3_BUCKET="…"
|
|
167
|
-
# …plus the usual key / region / endpoint settings for your driver
|
|
168
|
-
```
|
|
83
|
+
## Installation
|
|
169
84
|
|
|
170
|
-
|
|
85
|
+
Requires **Directus 9.26+ through 12.x**. Admins only. The extension must run in the Directus API process (not the sandbox).
|
|
171
86
|
|
|
172
|
-
|
|
87
|
+
### Marketplace
|
|
173
88
|
|
|
174
|
-
|
|
89
|
+
Search for **Storage Manager** in **Settings → Marketplace**. If install is blocked (this bundle includes an API), use npm or the manual steps below.
|
|
175
90
|
|
|
176
91
|
### npm
|
|
177
92
|
|
|
@@ -179,60 +94,17 @@ Requires **Directus 9.26+ through 12.x**. The extension must run in the Directus
|
|
|
179
94
|
npm install directus-extension-storage-manager
|
|
180
95
|
```
|
|
181
96
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
### Marketplace
|
|
185
|
-
|
|
186
|
-
Search for **Storage Manager** in **Settings → Marketplace**. This bundle includes an API endpoint, so some environments only allow App extensions from the Marketplace — use the npm/manual install below if install is blocked.
|
|
97
|
+
Put the package in your Directus `extensions` folder (or install it in a project that loads extensions from `node_modules`), then restart Directus.
|
|
187
98
|
|
|
188
99
|
### Manual installation
|
|
189
100
|
|
|
190
|
-
1. Install and build:
|
|
191
|
-
|
|
192
101
|
```bash
|
|
193
102
|
cd directus-extension-storage-manager
|
|
194
103
|
npm install
|
|
195
104
|
npm run build
|
|
196
105
|
```
|
|
197
106
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
3. Restart Directus.
|
|
201
|
-
|
|
202
|
-
4. In the Data Studio:
|
|
203
|
-
|
|
204
|
-
1. Open **Settings → Project Settings → Modules**
|
|
205
|
-
2. Enable **Storage Manager**
|
|
206
|
-
3. Open **Storage Manager** from the left bar
|
|
207
|
-
|
|
208
|
-
## Operator API (admin)
|
|
209
|
-
|
|
210
|
-
Base path: `/storage-manager`
|
|
211
|
-
|
|
212
|
-
| Method | Path | Purpose |
|
|
213
|
-
| --- | --- | --- |
|
|
214
|
-
| `GET` | `/storages` | List adapters + usage |
|
|
215
|
-
| `GET` | `/storages/:location/browse?path=` | Immediate physical folders |
|
|
216
|
-
| `GET` | `/storages/:location/folder-tree` | Nested physical tree |
|
|
217
|
-
| `POST` | `/storages/:location/folders` | Create folder (`name`, `parent_path`) |
|
|
218
|
-
| `PATCH` | `/storages/:location/folders` | Rename (`name`) and/or move (`parent_path`) |
|
|
219
|
-
| `DELETE` | `/storages/:location/folders` | Delete folders (`paths[]`, `mode: move\|delete`) |
|
|
220
|
-
| `POST` | `/storages/:location/move-files` | Relocate registered files on the same adapter |
|
|
221
|
-
| `POST` | `/storages/:location/place-file` | Nest a file under a path after upload |
|
|
222
|
-
| `GET` | `/storages/:location/orphans?path=` | Detect unknown objects (optional path scope) |
|
|
223
|
-
| `POST` | `/storages/:location/import-orphans` | Register orphans (reads image width/height) |
|
|
224
|
-
| `POST` | `/storages/:location/delete-orphans` | Delete orphans |
|
|
225
|
-
| `POST` | `/migrate/dry-run` | Count files/folders/conflicts without moving |
|
|
226
|
-
| `POST` | `/migrate` | Batch migrate (JSON result) |
|
|
227
|
-
| `POST` | `/migrate/stream` | SSE migrate progress |
|
|
228
|
-
| `POST` | `/materialize/dry-run` | Count materialize work |
|
|
229
|
-
| `POST` | `/materialize` | Materialize virtual folders onto storage |
|
|
230
|
-
| `POST` | `/materialize/stream` | SSE materialize progress |
|
|
231
|
-
| `GET` / `PATCH` | `/settings` | Read / merge settings |
|
|
232
|
-
|
|
233
|
-
**Move / migrate body (typical):** `target_storage`, `mode` (`move`; `copy` for the Flow operation), plus `file_ids` and/or `source_storage` (optional `source_path`, `preserve_paths`) and/or `folder_id` (optional `recursive`). Optional `target_path`, `source_folders`, `include_empty_folders`.
|
|
234
|
-
|
|
235
|
-
Same-adapter `move-files` skips a file when another registered row already owns the destination path.
|
|
107
|
+
Copy the built package into your Directus `extensions` folder (`package.json` and the `dist` folder), restart Directus, then enable **Storage Manager** under **Settings → Project Settings → Modules**.
|
|
236
108
|
|
|
237
109
|
## License
|
|
238
110
|
|
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 o from"node:fs";import{pathToFileURL as i}from"node:url";import s from"node:fs/promises";import{randomUUID as a}from"node:crypto";let c=null;async function l(e){try{const t=await import(e),n=t?.getStorage||t?.default?.getStorage;if("function"==typeof n)return n}catch{}return null}async function u(e){if(!o.existsSync(e))return null;try{const t=r(n.join(process.cwd(),"package.json"))(e),o=t?.getStorage||t?.default?.getStorage;if("function"==typeof o)return o}catch{}try{return await l(i(e).href)}catch{return null}}async function d(){if(c)return c;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 l(t);if(e)return c=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"],o=[];for(const e of t)for(const t of r)o.push(n.join(e,t));return o}()){const t=await u(e);if(t)return c=t,t}throw new Error("Could not resolve Directus getStorage(). Ensure this extension runs inside the Directus API process (not sandboxed).")}async function f(){return(await d())()}async function p(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 g(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 h(e,t){if("function"==typeof e.exists)return await e.exists(t);try{return await m(e,t),!0}catch{return!1}}async function m(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 y(e,t){if("function"!=typeof e.delete)throw new Error("Storage disk does not support delete");await e.delete(t)}async function*_(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 w=/__[a-f0-9]{16,}(?:\.[^.]+)?$/i;function v(e){const t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,""),r=n.posix.parse(t);return{dir:r.dir,stem:r.name}}function k(e,t){return e.startsWith(`${t}__`)&&w.test(e)}async function b(e,t){if("function"!=typeof e.list)return[];const{dir:r,stem:o}=v(t);if(!r)return[];const i=[];for await(const t of e.list(`${r}/${o}`)){const e=String(t||"").replace(/^[/\\]+/,""),s=n.posix.basename(e);n.posix.dirname(e)===r&&k(s,o)&&i.push(e)}return i}async function S(e,t){const n=await async function(e,t){if("function"!=typeof e.list)return[];const{stem:n}=v(t),r=[];for await(const t of e.list(n)){const e=String(t||"").replace(/^[/\\]+/,"");e.includes("/")||k(e,n)&&r.push(e)}return r}(e,t),r=await b(e,t);return[...new Set([...n,...r])]}async function $(e,t){const n=await S(e,t);for(const t of n)try{await y(e,t)}catch{}try{await y(e,t)}catch{}}const z={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 j(e,t){const n=e[t];if(null==n)return null;const r=String(n).trim();return""===r?null:r}function x(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 E(e,t){return j(e,`STORAGE_${t.toUpperCase()}_DRIVER`)||"local"}function A(e,t){return j(e,`STORAGE_${t.toUpperCase()}_ROOT`)}function P(e,t){return j(e,`STORAGE_${t.toUpperCase()}_BUCKET`)||j(e,`STORAGE_${t.toUpperCase()}_CONTAINER_NAME`)}async function O(e,t,r){const i=E(e,r),{file_count:s,total_bytes:a}=await async function(e,t){const n=await e("directus_files").where({storage:t}).select(e.raw("count(*) as file_count"),e.raw("coalesce(sum(filesize), 0) as total_bytes")).first();return{file_count:Number(n?.file_count||0),total_bytes:Number(n?.total_bytes||0)}}(t,r);let c={disk_total_bytes:null,disk_free_bytes:null,disk_used_bytes:null,disk_used_percent:null,disk_available:!1};return"local"===i&&(c=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",i=n.isAbsolute(e)?e:n.join(r,e);try{if(!o.existsSync(i))return t;const e=o.promises.statfs;if("function"==typeof e){const t=await e(i),n=Number(t.bsize||t.frsize||0),r=n*Number(t.blocks||0),o=n*Number(t.bavail??t.bfree??0),s=Math.max(0,r-o);return{disk_total_bytes:r||null,disk_free_bytes:o||null,disk_used_bytes:s||null,disk_used_percent:r>0?s/r*100:null,disk_available:r>0}}}catch{}return t}(A(e,r))),{location:r,driver:i,file_count:s,total_bytes:a,...c}}async function I(e,t,n){const r=await O(e,t,n),o=function(e){const t=String(e||"local").toLowerCase();return z[t]||{id:t,label:t,short:t.slice(0,8).toUpperCase(),icon:"storage"}}(r.driver);return{...r,label:o.label,short:o.short,icon:o.icon,root:A(e,n),bucket:P(e,n),folder_count:0,mirror_directus_folders:!1}}const Z="storage_manager",T=".keep",N={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 F(e){return String(e||"").replace(/\\/g,"/").replace(/^\/+|\/+$/g,"").replace(/\/+/g,"/")}function C(...e){return e.map(e=>F(e)).filter(Boolean).join("/")}function D(e,t,r,o=!1){const i=F(t),s=F(e);if(o)return s?i?`${i}/${s}`:s:i;const a=(r||[]).map(e=>F(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),o=r?`${t}/${r}`:t;return i?`${i}/${o}`:o}const c=n.posix.basename(s);return i?`${i}/${c}`:c}function U(e){return n.basename(e)===T}function B(e,t){const r=process.env.PWD||process.cwd()||"/directus",o=n.isAbsolute(e)?e:n.join(r,e),i=n.resolve(o,t);if(!i.startsWith(n.resolve(o)))throw new Error("Invalid storage path");return i}function M(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===T)throw new Error("Invalid folder name");return t}async function R(e,t,n){const r=new Set,o=E(n,e),i=A(n,e),a=F(t);if("local"===o&&i){const e=B(i,a||".");try{const t=await s.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 f()).location(e),n=a?`${a}/`:"";for await(const e of _(t,n)){const t=String(e||"").replace(/^[/\\]+/,"");if(!t.startsWith(n)&&n)continue;const o=n?t.slice(n.length):t,i=o.split("/")[0];i&&!i.startsWith(".")&&(o.includes("/")?r.add(i):U(t))}}catch{}return r}async function W(e,t,n){const r=new Set,o=F(n),i=await e("directus_files").select("filename_disk").where("storage",t),s=o?`${o}/`:"";for(const e of i){const t=String(e.filename_disk||"").replace(/^[/\\]+/,"");if(!t)continue;if(s&&!t.startsWith(s))continue;const n=s?t.slice(s.length):t,o=n.indexOf("/");if(o<=0)continue;const i=n.slice(0,o);i&&!i.startsWith(".")&&r.add(i)}return r}async function q(e,t,r){const o=new Set;if("local"===E(r,e))return o;const i=F(t),s=i?`${i}/`:"";try{const t=(await f()).location(e);for await(const e of _(t,s)){const t=String(e||"").replace(/^[/\\]+/,"");if(!U(t))continue;const r=F(n.posix.dirname(t));if(i){if(r===i)continue;if(!r.startsWith(`${i}/`))continue;const e=r.slice(i.length+1).split("/")[0];e&&!e.startsWith(".")&&o.add(e)}else{const e=r.split("/").filter(Boolean);1===e.length&&o.add(e[0])}}}catch{}return o}function L(e,t){const n=F(t).split("/").filter(Boolean);for(let t=1;t<=n.length;t++)e.add(n.slice(0,t).join("/"))}async function J(e,t){const r=new Set,o=await e("directus_files").select("filename_disk").where("storage",t);for(const e of o){const t=String(e.filename_disk||"").replace(/^[/\\]+/,"");if(!t||U(t))continue;const o=F(n.posix.dirname(t));o&&"."!==o&&L(r,o)}return r}async function V(e,t){const n=new Set,r=E(t,e),o=A(t,e);if("local"!==r||!o)return n;return await async function e(t){const r=B(o,t||".");let i;try{i=await s.readdir(r,{withFileTypes:!0})}catch{return}for(const r of i){if(!r.isDirectory()||!r.name||r.name.startsWith("."))continue;const o=C(t,r.name);n.add(o),await e(o)}}(""),n}async function G(e,t){const r=new Set;if("local"===E(t,e))return r;try{const t=(await f()).location(e);for await(const e of _(t,"")){const t=String(e||"").replace(/^[/\\]+/,"");if(!U(t))continue;const o=F(n.posix.dirname(t));o&&"."!==o&&L(r,o)}}catch{}return r}async function H(e,t,n){const r=new Set;for(const n of await J(e,t))r.add(n);for(const e of await V(t,n))r.add(e);for(const e of await G(t,n))r.add(e);return function(e){const t=Array.from(new Set(e.map(e=>F(e)).filter(Boolean))).sort((e,t)=>e.localeCompare(t)),n=new Map;for(const e of t){const t=e.includes("/")?e.slice(e.lastIndexOf("/")+1):e;n.set(e,{name:t,path:e})}const r=[];for(const e of t){const t=n.get(e),o=e.includes("/")?e.slice(0,e.lastIndexOf("/")):"";if(o&&n.has(o)){const e=n.get(o);e.children||(e.children=[]),e.children.push(t)}else r.push(t)}const o=e=>{e.sort((e,t)=>e.name.localeCompare(t.name));for(const t of e)t.children?.length&&o(t.children)};return o(r),r}(Array.from(r))}function K(e){let t=0;for(const n of e)t+=1,n.children?.length&&(t+=K(n.children));return t}async function X(e,t,n){try{return K(await H(e,t,n))}catch{return 0}}async function Y(e,t,r){const o=await async function(e,t,n){const r=new Set;for(const n of await J(e,t))r.add(n);for(const e of await V(t,n))r.add(e);for(const e of await G(t,n))r.add(e);return Array.from(r)}(e,t,r),i=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||U(t))continue;const r=F(n.posix.dirname(t));r&&"."!==r&&L(i,r)}return o.filter(e=>!i.has(e))}function Q(e,t,n){const r=F(e);if(!r)return"";if(null==t)return r;if(n?.length)return D(`${r}/__folder__`,t,n).replace(/\/__folder__$/,"");const o=F(t);return o?`${o}/${r}`:r}async function ee(e,t,n){const r=F(t);if(!r)return;let o="";for(const t of r.split("/").filter(Boolean))await re(e,t,o,n),o=C(o,t)}async function te(e,t,n){const r=F(t);if(!r)return;if("local"===E(n,e)){const t=A(n,e);if(!t)return;const o=B(t,r);try{await s.rm(o,{recursive:!0,force:!0})}catch{}return}try{const t=(await f()).location(e),n=`${r}/${T}`;await h(t,n)&&await y(t,n)}catch{}}async function ne(e){let t=await Y(e.database,e.sourceLocation,e.env);t=function(e,t,n){if(t?.length){const n=t.map(e=>F(e)).filter(Boolean);return e.filter(e=>n.some(t=>e===t||e.startsWith(`${t}/`)))}if(n){const t=F(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 n=0;for(const r of t){const t=Q(r,e.targetPath,e.sourceFolders);if(t)try{await ee(e.targetLocation,t,e.env),n+=1}catch(t){e.logger?.warn(`[storage-manager] Failed copying empty folder ${r}: ${t?.message||t}`)}}if(e.removeSource&&n)for(const n of[...t].sort((e,t)=>t.length-e.length))try{await te(e.sourceLocation,n,e.env),await se(e.sourceLocation,`${n}/.keep`,e.env)}catch{}return n}async function re(t,n,r,o){const i=C(r,M(n));if("local"===E(o,t)){const e=A(o,t);if(!e)throw new Error(`Local storage “${t}” has no STORAGE_${t.toUpperCase()}_ROOT`);const n=B(e,i);return await s.mkdir(n,{recursive:!0}),{path:i}}const a=(await f()).location(t),c=`${i}/${T}`;if(!await h(a,c)){const t=e.from([Buffer.alloc(0)]);await g(a,c,t,"application/octet-stream")}return{path:i}}async function oe(e,t,n,r,o,i,s,a=!1){const c=(await f()).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=D(d,r,s,a);if(d&&d!==f)try{if(!await h(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 h(c,f)){const e=await p(c,d);if(await g(c,f,e,n.type),!await h(c,f))throw new Error("Write verification failed")}try{const e=await b(c,d);for(const t of e)try{await y(c,t)}catch{}}catch{}await y(c,d),await e("directus_files").where("id",u).update({filename_disk:f}),await se(t,d,i),l.push({id:u,from:d,to:f,status:"moved"}),o?.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)}),o?.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 ie(e){const t=F(e),n=t.lastIndexOf("/");return-1===n?"":t.slice(0,n)}async function se(e,t,n){if(!n||"local"!==E(n,e))return;const r=A(n,e);if(!r)return;let o=ie(t);for(;o;){const e=B(r,o);try{if((await s.readdir(e)).length>0)return;await s.rmdir(e)}catch{return}o=ie(o)}}async function ae(t,r,o,i,a,c){const l=F(o),u=F(i);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(M(n.posix.basename(u)),await async function(e,t,r,o){const i=F(r);if(!i)return!1;if(await e("directus_files").select("id").where("storage",t).whereRaw("filename_disk LIKE ?",[`${i}/%`]).first())return!0;const s=ie(i),a=n.posix.basename(i),c=new Set;for(const n of await W(e,t,s))c.add(n);for(const e of await R(t,s,o))c.add(e);for(const e of await q(t,s,o))c.add(e);return c.has(a)}(t,r,u,a))throw new Error(`Folder already exists: ${u}`);const{moved:d,failed:m}=await ce(t,r,l,u,c);if(m>0)throw new Error(`Failed to relocate ${m} file(s) under ${l}`);if("local"===E(a,r)){const e=A(a,r);if(!e)throw new Error(`Local storage “${r}” has no STORAGE_${r.toUpperCase()}_ROOT`);const t=B(e,l),o=B(e,u);await s.mkdir(n.dirname(o),{recursive:!0});try{await s.access(t);try{await s.access(o);const e=await s.readdir(t,{withFileTypes:!0});for(const r of e){const e=n.join(t,r.name),i=n.join(o,r.name);try{await s.rename(e,i)}catch{}}await s.rm(t,{recursive:!0,force:!0})}catch{await s.rename(t,o)}}catch{await s.mkdir(o,{recursive:!0})}}else{const t=(await f()).location(r),n=`${l}/`;try{for await(const e of _(t,n)){const r=String(e||"").replace(/^[/\\]+/,"");if(!r.startsWith(n))continue;const o=u+r.slice(l.length);try{if(await h(t,o)){await y(t,r);continue}const e=await p(t,r);await g(t,o,e,"application/octet-stream"),await y(t,r)}catch(e){c?.warn(`[storage-manager] Folder leftover move failed ${r}: ${e?.message}`)}}}catch{}const o=`${u}/${T}`;if(!await h(t,o)){const n=e.from([Buffer.alloc(0)]);await g(t,o,n,"application/octet-stream")}const i=`${l}/${T}`;if(await h(t,i))try{await y(t,i)}catch{}}return c?.info(`[storage-manager] Relocated folder ${l} → ${u} on ${r} (${d} file(s))`),{path:u,moved:d,failed:m}}async function ce(e,t,n,r,o){const i=F(n),s=F(r);if(!i||i===s)return{moved:0,failed:0};const a=await e("directus_files").select("id","filename_disk","type").where("storage",t).whereRaw("filename_disk LIKE ?",[`${i}/%`]);if(!a.length)return{moved:0,failed:0};const c=(await f()).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(`${i}/`))continue;if(U(a))continue;const d=a.slice(i.length).replace(/^\//,""),f=s?`${s}/${d}`:d;try{if(a===f){l++;continue}if(!await h(c,a)){await e("directus_files").where("id",r).update({filename_disk:f}),l++,o?.warn(`[storage-manager] Prefix relocate DB-only (missing source): ${a} → ${f}`);continue}if(await h(c,f))throw new Error(`Target already exists: ${f}`);const i=await p(c,a);if(await g(c,f,i,n.type),!await h(c,f))throw new Error("Write verification failed");try{const e=await b(c,a);for(const t of e)try{await y(c,t)}catch{}}catch{}await y(c,a),await e("directus_files").where("id",r).update({filename_disk:f}),l++,o?.info(`[storage-manager] Prefix relocate ${a} → ${f} on ${t}`)}catch(e){u++,o?.warn(`[storage-manager] Prefix relocate failed for ${r}: ${e?.message}`)}}return{moved:l,failed:u}}function le(e){return String(e.title||e.filename_download||e.filename_disk||e.id)}async function ue(e,t,n,r){await $(e,t.filename_disk);try{await se(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 de(e,t,n,r){const o=new Array(e.length);let i=0;const s=Array.from({length:Math.min(t,e.length)||1},()=>async function(){for(;i<e.length;){if(r?.())return;const t=i++;o[t]=await n(e[t],t)}}());return await Promise.all(s),o}async function fe(e,t,r,o){let i;try{i=await S(e,r)}catch(e){return void o?.warn?.(`[storage-manager] Could not list asset transforms for ${r}: ${e instanceof Error?e.message:String(e)}`)}for(const r of i)try{const o=n.posix.basename(r);if(await h(t,o))continue;const i=await p(e,r);await g(t,o,i,null)}catch(e){o?.warn?.(`[storage-manager] Failed copying asset transform ${r}: ${e instanceof Error?e.message:String(e)}`)}}async function pe(e,n,r,o,i,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 y=await f(),_=y.location(e.storage),w=y.location(n);if(!await h(_,e.filename_disk))return{...u,status:"failed",error:`Source object missing on ${e.storage}`};if(await o("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 h(w,d)){if(await fe(_,w,e.filename_disk,i),await o("directus_files").where({id:e.id}).update({storage:n,filename_disk:d}),"move"===r&&!c)try{await ue(_,e,l,i)}catch(t){i?.warn?.(`[storage-manager] DB updated but failed deleting source ${e.id}: ${t instanceof Error?t.message:String(t)}`)}const t=await m(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 p(_,e.filename_disk),k=s?v.pipe((b=s,new t({transform(e,t,n){const r=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e);r>0&&b(r),n(null,e)}}))):v;var b;try{await g(w,d,k,e.type)}catch(e){try{await h(w,d)&&await $(w,d)}catch{}return{...u,status:"failed",error:`Write failed: ${e instanceof Error?e.message:String(e)}`}}if(!await h(w,d))return{...u,status:"failed",error:"Target write did not persist (exists check failed)"};let S=0;try{S=(await m(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&&S>0){const t=Number(e.filesize);if(Math.abs(t-S)>Math.max(64,.01*t)&&S<.95*t){try{await $(w,d)}catch{}return{...u,status:"failed",error:`Size mismatch after write (expected ~${t}, got ${S})`}}}await fe(_,w,e.filename_disk,i);try{await o("directus_files").where({id:e.id}).update({storage:n,filename_disk:d})}catch(e){try{await $(w,d)}catch{}return{...u,status:"failed",error:`DB update failed: ${e instanceof Error?e.message:String(e)}`}}if("move"===r&&!c)try{await ue(_,e,l,i)}catch(t){return i?.warn?.(`[storage-manager] Moved ${e.id} to ${n} but source delete failed: ${t instanceof Error?t.message:String(t)}`),{...u,status:"moved",bytes:S,error:`Moved, but source cleanup failed: ${t instanceof Error?t.message:String(t)}`}}return{...u,status:"move"===r?"moved":"copied",bytes:S}}async function ge(e){const{fileIds:t,targetStorage:n,mode:r,database:o,logger:i,onProgress:s,isCancelled:a,keepSourceFileOnDisk:c,targetPath:l,sourceFolders:u,preservePaths:d,includeEmptyFolders:f,sourceStorage:p,sourcePath:g,env:h}=e,m=Math.min(8,Math.max(1,Number(e.concurrency)||3)),y=Date.now(),_=Array.from(new Set(t.filter(Boolean)));async function w(e){if(!f||!h||a?.())return;const t=p||e||null;if(t&&t!==n)try{await ne({database:o,sourceLocation:t,targetLocation:n,env:h,targetPath:l,sourceFolders:u,sourcePath:g,removeSource:"move"===r&&!c,logger:i})}catch(e){i?.warn?.(`[storage-manager] Empty folder copy failed: ${e instanceof Error?e.message:String(e)}`)}}if(0===_.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 o("directus_files").select("id","storage","filename_disk","filename_download","title","type","filesize").whereIn("id",_),k=new Map(v.map(e=>[String(e.id),e])),b=v.reduce((e,t)=>e+(Number(t.filesize)||0),0),S=v.length&&v.every(e=>e.storage===v[0].storage)?v[0].storage:null;s?.({type:"start",mode:r,from:S,to:n,total:_.length,total_bytes:b});let $=0,z=0,j=0,x=0,E=0;const A=new Map;let P=0;const O=await de(_,m,async e=>{if(a?.())return{id:e,filename_disk:"",from:"",to:n,status:"failed",error:"Cancelled"};const t=k.get(e),f=++E;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:_.length,result:t,name:e,succeeded:z,skipped:j,failed:x,transferred_bytes:$,total_bytes:b,elapsed_ms:Date.now()-y}),t}let p;s?.({type:"file_start",index:f,total:_.length,id:t.id,name:le(t),filename_disk:t.filename_disk,from:t.storage,to:n,bytes:Number(t.filesize)||0}),A.set(t.id,0);try{p=await pe(t,n,r,o,i,e=>((e,t,n)=>{$+=n;const r=(A.get(t.id)||0)+n;A.set(t.id,r);const o=Date.now();o-P<120||(P=o,s?.({type:"file_bytes",index:e,id:t.id,file_transferred:r,file_bytes:Number(t.filesize)||0,transferred_bytes:$,total_bytes:b,elapsed_ms:o-y}))})(f,t,e),null!=l?function(e,t,n,r=!1){return D(e,t,n,r)}(t.filename_disk,l,u,d):void 0,Boolean(c),h)}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=A.get(t.id)||0,n=Number(p.bytes)||Number(t.filesize)||0;n>e&&($+=n-e,A.set(t.id,n))}else"skipped"===p.status?j+=1:x+=1;return s?.({type:"file_done",index:f,total:_.length,result:p,name:le(t),succeeded:z,skipped:j,failed:x,transferred_bytes:$,total_bytes:b,elapsed_ms:Date.now()-y}),p},a);await w(S);const I={mode:r,target_storage:n,total:O.filter(Boolean).length,succeeded:z,skipped:j,failed:x,results:O.filter(Boolean),transferred_bytes:$,total_bytes:b,elapsed_ms:Date.now()-y};return i?.info?.(`[storage-manager] ${r} → ${n}: ${z} ok, ${j} skipped, ${x} failed (of ${I.total})`),s?.({type:"done",data:I}),I}const he=new Set(["image/jpeg","image/jpg","image/png","image/webp","image/gif","image/tiff","image/tif","image/avif"]);let me;function ye(e){if(!e)return!1;const t=e.toLowerCase();return"image/svg+xml"!==t&&(he.has(t)||t.startsWith("image/"))}async function _e(e){const t=await async function(){if(void 0!==me)return me;try{const e=r(n.join(process.cwd(),"package.json"))("sharp"),t="function"==typeof e?e:e?.default;if("function"==typeof t)return me=t,me}catch{}try{const e=await import("sharp"),t="function"==typeof e.default?e.default:e;if("function"==typeof t)return me=t,me}catch{}return me=null,null}();if(!t)return null;try{const n=await t(e,{failOn:"none"}).metadata();let r=n.width??0,o=n.height??0;if(n.orientation&&n.orientation>=5){const e=r;r=o,o=e}if(r>0&&o>0)return{width:r,height:o}}catch{}return null}async function we(e,t){let n,r;try{n=await p(e,t)}catch{return null}try{r=await async function(e,t){const n=[];let r=0;try{for await(const o of e){const e=Buffer.isBuffer(o)?o:Buffer.from(o);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 o=Buffer.concat(n);return o.length>t?o.subarray(0,t):o}(n,2097152)}catch{return null}return r.length?await _e(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 ve=/__[a-f0-9]{16,}(?:\.[^.]+)?$/i;function ke(e){return ve.test(n.basename(e))}function be(e){const t=n.basename(e);return!(t&&!t.startsWith("."))||("directus-health-file"===t||!!ke(e))}const Se={".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 $e(e){const t=n.extname(e).toLowerCase();return Se[t]||null}function ze(e){const t=n.parse(n.basename(e)).name;return t.replace(/_/g," ").replace(/\s+/g," ").trim()||t||e}function je(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 xe(e,t){const r=new Set;if(t){const o=E(t,e),i=A(t,e);if("local"===o&&i){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,o=""){let i;try{i=await s.readdir(t,{withFileTypes:!0})}catch{return}for(const s of i){const i=o?`${o}/${s.name}`:s.name;s.isDirectory()?await e(n.join(t,s.name),i):s.isFile()&&(be(i)||r.push(i))}}(t),r}(i))r.add(e);return Array.from(r)}}const o=(await f()).location(e);try{for await(const e of _(o,"")){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,o){const i=String(o||"").replace(/\\/g,"/").replace(/^\/+|\/+$/g,"").replace(/\/+/g,"/"),s=await xe(t,r),a=i?s.filter(e=>e===i||e.startsWith(`${i}/`)):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 f()).location(t),d=[];for(const e of a){if(l.has(e))continue;let t=0;try{const n=await m(u,e);t=Number(n.size)||0}catch{t=0}d.push({filename_disk:e,filesize:t,type:$e(e),suggested_id:je(e),filename_download:n.basename(e),title:ze(e)})}return d.sort((e,t)=>e.filename_disk.localeCompare(t.filename_disk)),{orphans:d,scanned:a.length,known:l.size,path:i}}let Ae=null;function Pe(){Ae=null}async function Oe(e){if(Ae)return Ae;const t=await e("directus_settings").select(Z).first(),n=t?.[Z],r="string"==typeof n?JSON.parse(n):n??{},o={locations:r.locations??{}};return r&&"object"==typeof r&&"name_mirror_claims"in r&&(o.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)),Ae=o,Ae}async function Ie(e,t){await e("directus_settings").update({[Z]:JSON.stringify(t)}),Ae=t}function Ze(e,t){return{...N,...e.locations[t]??{}}}function Te(e,t){return`${e??""}::${t}`}function Ne(e){const t=new Map;for(const n of e){const e=Te(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 Fe(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 Ce(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 De(e,t){const n=await Oe(e);if(void 0!==n.name_mirror_claims)return n.name_mirror_claims;const r=function(e){const t={},n=Ne(e);for(const[e,r]of n)r[0]&&(t[e]=r[0]);return t}(await Fe(e)),o={...n,name_mirror_claims:r};return await Ie(e,o),t?.info(`[storage-manager] Initialized name_mirror_claims (${Object.keys(r).length} sibling groups)`),r}async function Ue(e,t){const n=await Oe(e);await Ie(e,{...n,name_mirror_claims:t})}async function Be(e,t,n){const r=await t("directus_folders").select("id","name","parent").where("id",e).first();if(!r)return;const o=String(r.name),i=r.parent?String(r.parent):null,s=Te(i,o),a={...await De(t,n)};0!==(await Ce(t,i,o)).filter(t=>t!==e).length?a[s]:a[s]!==e&&(a[s]=e,await Ue(t,a))}async function Me(e,t,n,r,o,i){if(t===n)return;const s={...await De(o,i)},a=Te(r,t),c=Te(r,n);let l=!1;s[a]===e&&(delete s[a],l=!0);0===(await Ce(o,r,n)).filter(t=>t!==e).length?s[c]!==e&&(s[c]=e,l=!0):s[c]===e||s[c],l&&await Ue(o,s)}async function Re(e,t,n,r,o){const i={...await De(r,o)},s=Te(t,n);i[s]===e&&(delete i[s],await Ue(r,i))}async function We(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 qe(e){return"folder"===e}function Le(e){return"folder_id"===e}function Je(e){return qe(t=e.prefix_strategy)||Le(t);var t}function Ve(e,t,n,r){return(n.length?n:[t]).length<=1||r===t?e:`${e}_${t}`}async function Ge(e,t){if(!t)return null;return Ke(await Fe(e),t,"name",await De(e))}async function He(e,t){if(!t)return null;return Ke(await Fe(e),t,"id")}function Ke(e,t,n,r={}){if(!t)return null;const o=new Map;for(const t of e)o.set(t.id,t);const i="name"===n?Ne(e):null,s=[];let a=String(t),c=0;for(;a&&c<50;){const e=o.get(a);if(!e)break;if("id"===n)s.unshift(a);else{const t=Te(e.parent,e.name),n=i.get(t)??[e.id];s.unshift(Ve(e.name,e.id,n,r[t]??null))}a=e.parent,c++}return s.length?s.join("/"):null}async function Xe(e,t,n){switch(e.prefix_strategy){case"none":default:return null;case"folder":return await Ge(n,t.folder)||null;case"folder_id":return await He(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 Ye(e){return String(e||"").replace(/\\/g,"/").replace(/\//g,"_").trim()}function Qe(e,t){if(!e)return"";const n=[];let r=e,o=0;for(;r&&o<100;){const e=t.get(r);if(!e)break;n.unshift(Ye(e.name)),r=e.parent,o+=1}return n.filter(Boolean).join("/")}async function et(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 o=[],i=[t];for(;i.length;){const e=i.pop();o.push(e);for(const t of r.get(e)||[])i.push(t)}return o}async function tt(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}])),o=await et(e.database,e.folderId);let i=e.database("directus_files").select("id","storage","filename_disk","filesize","type","folder").whereNotNull("filename_disk");e.recursive?null!==e.folderId&&(i=i.whereIn("folder",[e.folderId,...o])):i=null===e.folderId?i.whereNull("folder"):i.whereIn("folder",o);const s=await i,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 o=s[t];if(e.isCancelled?.())break;const i="merge"===e.mode?String(e.targetStorage||""):String(o.storage),g=Qe(o.folder?String(o.folder):null,r),h=n.posix.basename(String(o.filename_disk||"")),m=g?`${g}/${h}`:h,y=String(o.filename_disk||o.id);if(e.onProgress?.({type:"file_start",index:t+1,total:s.length,id:String(o.id),name:y,filename_disk:String(o.filename_disk||""),from:String(o.storage),to:i,bytes:Number(o.filesize)||0}),e.structureOnly){const n={id:o.id,status:"skipped",filename_disk:m,from:String(o.storage),to:i,error:"Structure-only mode"};a.push(n),u+=1,e.onProgress?.({type:"file_done",index:t+1,total:s.length,result:n,name:y,succeeded:c,skipped:u,failed:l,transferred_bytes:p,total_bytes:d,elapsed_ms:Date.now()-f});continue}try{const n=await pe(o,i,"move",e.database,e.logger,void 0,m,Boolean(e.keepSourceFileOnDisk));a.push(n),"failed"===n.status?l+=1:"skipped"===n.status?u+=1:(c+=1,p+=Number(n.bytes)||Number(o.filesize)||0),e.onProgress?.({type:"file_done",index:t+1,total:s.length,result:n,name:y,succeeded:c,skipped:u,failed:l,transferred_bytes:p,total_bytes:d,elapsed_ms:Date.now()-f})}catch(n){const r={id:o.id,status:"failed",filename_disk:m,from:String(o.storage),to:i,error:n?.message||"Materialize failed"};a.push(r),l+=1,e.onProgress?.({type:"file_done",index:t+1,total:s.length,result:r,name:y,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 nt="directus-extension-storage-manager",rt=`https://www.npmjs.com/package/${nt}`;let ot=null;const it=18e5;function st(e){return String(e||"").trim().replace(/^v/,"")}function at(e){const t=st(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("."):[]}}async function ct(e=!1){if(!e&&ot&&Date.now()<ot.expiresAt)return ot.data;const t=st("1.1.1"),n={npm:rt,github:"https://github.com/domdus/directus-extension-storage-manager",marketplace:null},r={current_version:t,latest_version:null,has_update:!1,registry:"npm",checked_at:(new Date).toISOString(),release_url:n.npm,links:n};try{const e=await fetch(`https://registry.npmjs.org/${encodeURIComponent(nt)}`,{method:"GET",headers:{Accept:"application/json"}});if(!e.ok)throw new Error(`npm registry request failed (${e.status})`);const n=await e.json(),o=st(n?.["dist-tags"]?.latest||"");if(!o)throw new Error("No latest version found in npm dist-tags");const i=function(e,t){const n=at(e),r=at(t),o=Math.max(n.nums.length,r.nums.length,3);for(let e=0;e<o;e++){const t=n.nums[e]??0,o=r.nums[e]??0;if(t>o)return 1;if(t<o)return-1}if(!n.prerelease.length&&r.prerelease.length)return 1;if(n.prerelease.length&&!r.prerelease.length)return-1;const i=Math.max(n.prerelease.length,r.prerelease.length);for(let e=0;e<i;e++){const t=n.prerelease[e],o=r.prerelease[e];if(null==t)return-1;if(null==o)return 1;const i=/^[0-9]+$/.test(t)?parseInt(t,10):null,s=/^[0-9]+$/.test(o)?parseInt(o,10):null;if(null==i||null==s){if(null!=i&&null==s)return-1;if(null==i&&null!=s)return 1;if(t>o)return 1;if(t<o)return-1}else{if(i>s)return 1;if(i<s)return-1}}return 0}(o,t)>0,s={...r,latest_version:o,has_update:i,release_url:i?`${rt}?activeTab=versions`:rt,checked_at:(new Date).toISOString()};return ot={data:s,expiresAt:Date.now()+it},s}catch(e){const t={...r,error:e?.message||"Update check failed",checked_at:(new Date).toISOString()};return ot={data:t,expiresAt:Date.now()+Math.min(3e5,it)},t}}function lt(e,t){return!(!(n=e.accountability)||"object"!=typeof n||!0!==n.admin)||(t.status(403).json({errors:[{message:"Admin access required",extensions:{code:"FORBIDDEN"}}]}),!1);var n}async function ut(e,t,n){if(!t)return[];if(!n)return[t];const r=await e("directus_folders").select("id","parent"),o=new Map;for(const e of r){const t=null==e.parent?null:String(e.parent),n=String(e.id);o.has(t)||o.set(t,[]),o.get(t).push(n)}const i=[],s=[String(t)];for(;s.length;){const e=s.pop();i.push(e);const t=o.get(e)||[];for(const e of t)s.push(e)}return i}async function dt(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");t.source_storage&&n.where("storage",String(t.source_storage));const r=null!=t.source_path?F(String(t.source_path)):"";if(r){if(!t.source_storage)return[];const e=`${r}/`;!1===t.recursive?n.where("filename_disk","like",`${e}%`).whereNot("filename_disk","like",`${e}%/%`):n.where("filename_disk","like",`${e}%`)}if(void 0!==t.folder_id)if(null===t.folder_id||""===t.folder_id)n.whereNull("folder");else{const r=await ut(e,String(t.folder_id),Boolean(t.recursive));0===r.length?n.where("folder",String(t.folder_id)):n.whereIn("folder",r)}return(await n).map(e=>String(e.id))}var ft={id:"storage-manager",handler:(e,t)=>{const{database:r,env:o,logger:i}=t;e.get("/storages",async(e,t,n)=>{try{if(!lt(e,t))return;const n=x(o),i=await Oe(r),s=await Promise.all(n.map(async e=>{const t=await I(o,r,e);return t.folder_count=await X(r,e,o),t.mirror_directus_folders=Je(Ze(i,e)),t}));t.json({data:s})}catch(e){n(e)}}),e.get("/update-check",async(e,t,n)=>{try{if(!lt(e,t))return;const n="1"===String(e.query.force||""),r=await ct(n);t.json({data:r})}catch(e){n(e)}}),e.get("/storages/:location",async(e,t,n)=>{try{if(!lt(e,t))return;const n=String(e.params.location);if(!x(o).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const i=await I(o,r,n);i.folder_count=await X(r,n,o);const s=await Oe(r);i.mirror_directus_folders=Je(Ze(s,n)),t.json({data:i})}catch(e){n(e)}}),e.get("/storages/:location/browse",async(e,t,n)=>{try{if(!lt(e,t))return;const n=String(e.params.location);if(!x(o).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const i=F(String(e.query.path||"")),s=await async function(e,t,n,r){const o=F(n),i=new Set;for(const n of await W(e,t,o))i.add(n);for(const e of await R(t,o,r))i.add(e);for(const e of await q(t,o,r))i.add(e);const s=Array.from(i).sort((e,t)=>e.localeCompare(t)).map(e=>({name:e,path:C(o,e)}));return{path:o,folders:s}}(r,n,i,o);t.json({data:s})}catch(e){n(e)}}),e.get("/storages/:location/folder-tree",async(e,t,n)=>{try{if(!lt(e,t))return;const n=String(e.params.location);if(!x(o).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const i=await H(r,n,o);t.json({data:i})}catch(e){n(e)}}),e.post("/storages/:location/folders",async(e,t,n)=>{try{if(!lt(e,t))return;const n=String(e.params.location);if(!x(o).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const r=e.body||{},i=await re(n,String(r.name||""),String(r.parent_path||""),o);t.json({data:i})}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,a)=>{try{if(!lt(e,n))return;const a=String(e.params.location);if(!x(o).includes(a))return void n.status(404).json({errors:[{message:`Unknown storage location: ${a}`}]});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 p=await async function(e,t,n,r,o,i){const a="delete"===i?.mode?"delete":"move",c=[],l=[];let u=0,d=0;const p=E(r,t),g=(await f()).location(t);for(const f of n){const n=F(f);if(!n){l.push({path:String(f),error:"Invalid path"});continue}const m=ie(n);try{let f=0;if("delete"===a){const r=(await e("directus_files").select("id","filename_disk").where("storage",t).whereRaw("filename_disk LIKE ?",[`${n}/%`])).filter(e=>!U(String(e.filename_disk||""))),o=r.map(e=>String(e.id));if(o.length){if(i?.filesService)await i.filesService.deleteMany(o);else for(const t of r){const n=String(t.id),r=String(t.filename_disk||"");try{r&&await $(g,r)}catch{}await e("directus_files").where("id",n).delete()}f=o.length,d+=o.length}}else{const{moved:r,failed:i}=await ce(e,t,n,m,o);if(u+=r,i>0){l.push({path:n,error:`Could not move ${i} registered file(s) to parent`});continue}}if("local"===p){const e=A(r,t);if(!e)throw new Error("Missing local root");const o=B(e,n);await s.rm(o,{recursive:!0,force:!0})}else try{for await(const e of _(g,`${n}/`)){const t=String(e||"").replace(/^[/\\]+/,"");if(t.startsWith(`${n}/`)&&U(t))try{await y(g,t)}catch{}}}catch{const e=`${n}/${T}`;await h(g,e)&&await y(g,e)}c.push(n),o?.info("delete"===a?`[storage-manager] Deleted storage folder “${n}” on ${t} (deleted ${f} 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,a,l,o,i,{mode:u,filesService:d});n.json({data:p})}catch(e){a(e)}}),e.patch("/storages/:location/folders",async(e,t,s)=>{try{if(!lt(e,t))return;const s=String(e.params.location);if(!x(o).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=C(String(a.parent_path??""),e);d=await ae(r,s,c,t,o,i)}else d=l?await async function(e,t,n,r,o,i){const s=F(n);if(!s)throw new Error("Folder path is required");const a=M(r);return ae(e,t,s,C(ie(s),a),o,i)}(r,s,c,String(a.name||""),o,i):await async function(e,t,r,o,i,s){const a=F(r);if(!a)throw new Error("Folder path is required");return ae(e,t,a,C(F(o),n.posix.basename(a)),i,s)}(r,s,c,String(a.parent_path??""),o,i);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(!lt(e,t))return;const n=String(e.params.location);if(!x(o).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 oe(r,n,a,String(s.target_path??""),i,o,c,Boolean(s.preserve_paths)):{moved:0,failed:0,skipped:0,results:[]};!1!==s.include_empty_folders&&(c.length||s.source_storage)&&await ne({database:r,sourceLocation:String(s.source_storage||n),targetLocation:n,env:o,targetPath:String(s.target_path??""),sourceFolders:c.length?c:void 0,removeSource:!0,logger:i}),t.json({data:l})}catch(e){n(e)}}),e.post("/storages/:location/place-file",async(e,t,i)=>{try{if(!lt(e,t))return;const i=String(e.params.location);if(!x(o).includes(i))return void t.status(404).json({errors:[{message:`Unknown storage location: ${i}`}]});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,o){const i=F(o);if(!i)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===`${i}/${c}`)return a;const l=(await oe(e,r,[t],i)).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),i,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(!lt(e,t))return;const n=String(e.params.location);if(!x(o).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const i="string"==typeof e.query.path?e.query.path:"",s=await Ee(r,n,o,i);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(!lt(e,t))return;const s=String(e.params.location);if(!x(o).includes(s))return void t.status(404).json({errors:[{message:`Unknown storage location: ${s}`}]});const c=e.body||{};let l=Array.isArray(c.filename_disks)?c.filename_disks.map(String):[];if(0===l.length){l=(await Ee(r,s,o,c.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,o){const i=(await f()).location(t),s=[];for(const c of r){const r=String(c||"").trim();if(r&&!be(r))try{const c=await e("directus_files").select("id").where({storage:t,filename_disk:r}).first();if(c){s.push({filename_disk:r,id:String(c.id),status:"skipped",error:"Already in database"});continue}if(!await h(i,r)){s.push({filename_disk:r,status:"failed",error:"File not found on disk"});continue}const l=await m(i,r),u=je(r);let d=u||a();u&&await e("directus_files").select("id").where({id:u}).first()&&(d=a());const f=new Date,p=n.basename(r),g=$e(r),y=ze(r);let _=null,w=null;if(ye(g)){const e=await we(i,r);e&&(_=e.width,w=e.height)}await e("directus_files").insert({id:d,storage:t,filename_disk:r,filename_download:p,title:y,type:g,filesize:Number(l.size)||0,width:_,height:w,folder:o?.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===c.folder?null:c.folder});i.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(!lt(e,t))return;const n=String(e.params.location);if(!x(o).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 f()).location(t),o=[];for(const i of n){const n=String(i||"").trim();if(n&&!be(n))try{if(await e("directus_files").select("id").where({storage:t,filename_disk:n}).first()){o.push({filename_disk:n,status:"skipped",error:"Registered in Directus — use File Library to delete"});continue}if(!await h(r,n)){o.push({filename_disk:n,status:"skipped",error:"Not found on disk"});continue}await y(r,n),o.push({filename_disk:n,status:"deleted"})}catch(e){o.push({filename_disk:n,status:"failed",error:e?.message||String(e)})}else o.push({filename_disk:n,status:"skipped",error:n&&ke(n)?"Generated thumbnail":"Ignored path"})}return o}(r,n,a);i.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(!lt(e,t))return;const n=e.query.storage?String(e.query.storage):null,o=void 0!==e.query.folder?"null"===e.query.folder||""===e.query.folder?null:String(e.query.folder):void 0,i=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!==o)if(null===o)d.whereNull("folder");else if(a){const e=await ut(r,o,!0);d.whereIn("folder",e)}else d.where("folder",o);if(i){const e=`%${i.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,h=u.startsWith("-")?"desc":"asc",m=new Set(["uploaded_on","modified_on","filename_download","filesize","title","storage","type"]).has(g)?g:"uploaded_on",y=await d.clone().orderBy(m,h).limit(l).offset((c-1)*l),_=await f,w=await p,v=Number(_?.count||0),k=Number(w?.total_bytes||0);t.json({data:y,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(!lt(e,t))return;const n=void 0===e.query.parent?void 0:"null"===e.query.parent||""===e.query.parent?null:String(e.query.parent),o=e.query.storage?String(e.query.storage):null;let i=r("directus_folders").select("id","name","parent").orderBy("name","asc");null===n?i=i.whereNull("parent"):void 0!==n&&(i=i.where("parent",n));const s=await i,a=[];for(const e of s){const t=String(e.id);let n=r("directus_files").where("folder",t);o&&(n=n.andWhere("storage",o));const i=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(i?.file_count||0),total_bytes:Number(i?.total_bytes||0),child_count:Number(s?.count||0)})}let c=null;if(null==n){let e=r("directus_files").whereNull("folder");o&&(e=e.andWhere("storage",o));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(!lt(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(!lt(e,t))return;const n=String(e.params.id),o=[];let i=n;for(let e=0;e<50&&i;e++){const e=await r("directus_folders").select("id","name","parent").where({id:i}).first();if(!e)break;o.unshift({id:String(e.id),name:e.name}),i=null==e.parent?null:String(e.parent)}t.json({data:o})}catch(e){n(e)}}),e.post("/migrate/dry-run",async(e,t,n)=>{try{if(!lt(e,t))return;const n=e.body||{},i=String(n.target_storage||"").trim(),s=x(o);if(!i||!s.includes(i))return void t.status(400).json({errors:[{message:"Provide a valid target_storage"}]});const a=null!=n.target_path?String(n.target_path):"",c=Boolean(n.preserve_paths),l=Array.isArray(n.source_folders)?n.source_folders.map(String):[],u=await dt(r,n),d=u.length?await r("directus_files").select("id","storage","filesize","filename_disk").whereIn("id",u):[],f=new Set,p=[],g=d.map(e=>{const t=String(e.filename_disk||""),n=D(t,a,l,c),r=F(n.includes("/")?n.slice(0,n.lastIndexOf("/")):"");return r&&f.add(r),{id:String(e.id),storage:String(e.storage),from:t,to:n}}),h=[...new Set(g.map(e=>e.to).filter(Boolean))],m=h.length?await r("directus_files").select("id","filename_disk").where({storage:i}).whereIn("filename_disk",h):[],y=new Map;for(const e of m)y.set(String(e.filename_disk),String(e.id));let _=0;for(const e of g){const t=y.get(e.to),n=Boolean(t&&t!==e.id);n&&(_+=1),p.length<20&&p.push({from:`${e.storage}:${e.from}`,to:`${i}:${e.to}`,skipped:n})}let w=0;const v=n.source_storage?String(n.source_storage):"";if(v&&s.includes(v)){const e=null!=n.source_path?F(String(n.source_path)):"",t=(await Y(r,v,o)).filter(t=>l.length?l.some(e=>{const n=F(e);return t===n||t.startsWith(`${n}/`)}):!e||(t===e||t.startsWith(`${e}/`)));w=t.length;for(const e of t){const t=Q(e,a,l.length?l:void 0);t&&f.add(t)}}t.json({data:{total_files:d.length,total_folders:f.size,empty_folders:w,total_bytes:d.reduce((e,t)=>e+(Number(t.filesize)||0),0),skipped:_,samples:p}})}catch(e){n(e)}}),e.post("/migrate",async(e,t,n)=>{try{if(!lt(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=x(o);if(!c.includes(s))return void t.status(400).json({errors:[{message:`Unknown target storage: ${s}. Available: ${c.join(", ")}`}]});if(E(o,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 dt(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.`}]});i.info(`[storage-manager] Starting ${a} of ${l.length} file(s) → ${s} (by ${e.accountability?.user||"unknown"})`);const d=await ge({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:i,env:o});t.json({data:d})}catch(e){n(e)}}),e.post("/migrate/stream",async(e,t,n)=>{try{if(!lt(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=x(o);if(!c.includes(s))return void t.status(400).json({errors:[{message:`Unknown target storage: ${s}. Available: ${c.join(", ")}`}]});if(E(o,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 dt(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)};i.info(`[storage-manager] Streaming ${a} of ${l.length} file(s) → ${s} (by ${e.accountability?.user||"unknown"})`);try{await ge({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:i,env:o,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,i)=>{try{if(!lt(e,t))return;const i=e.body||{},s="merge"===i.mode?"merge":"preserve",a=void 0===i.folder_id||null===i.folder_id||""===i.folder_id?null:String(i.folder_id),c=String(i.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(!x(o).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}])),o=await et(e.database,e.folderId);let i=e.database("directus_files").select("id","storage","filename_disk","filesize","folder").whereNotNull("filename_disk");e.recursive?null!==e.folderId&&(i=i.whereIn("folder",[e.folderId,...o])):i=null===e.folderId?i.whereNull("folder"):i.whereIn("folder",o);const s=await i,a=await f(),c=new Set;let l=0;const u=new Map,d=[];for(const t of s){const o="merge"===e.mode?String(e.targetStorage||""):String(t.storage),i=Qe(t.folder?String(t.folder):null,r),s=n.posix.basename(String(t.filename_disk||"")),f=i?`${i}/${s}`:s,p=`${o}::${f}`;c.has(p)&&(l+=1),c.add(p);const g=String(t.filename_disk||"").replace(/\\/g,"/").replace(/^\/+/,"");if(t.storage!==o||g!==f)try{const e=a.location(o);await h(e,f)&&(l+=1)}catch{}d.length<25&&d.push({id:String(t.id),from:`${t.storage}:${t.filename_disk}`,to_storage:o,to_path:f});const m=u.get(o)||{files:0,bytes:0};m.files+=1,m.bytes+=Number(t.filesize)||0,u.set(o,m)}const p=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:p.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(i.structure_only),recursive:Boolean(i.recursive)});t.json({data:l})}catch(e){i(e)}}),e.post("/materialize",async(e,t,n)=>{try{if(!lt(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(!x(o).includes(c))return void t.status(400).json({errors:[{message:`Unknown target storage: ${c}`}]})}const l=await tt({database:r,logger:i,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(!lt(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(!x(o).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 tt({database:r,logger:i,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(!lt(e,t))return;const n=await r("directus_settings").select(Z).first(),o=n?.[Z],i="string"==typeof o?JSON.parse(o):o??{};t.json({data:{locations:i.locations??{}}})}catch(e){n(e)}}),e.patch("/settings",async(e,t,n)=>{try{if(!lt(e,t))return;const n=e.body;if(!n||"object"!=typeof n.locations)return void t.status(400).json({errors:[{message:'Body must contain a "locations" object.'}]});const o=await r("directus_settings").select(Z).first(),i=o?.[Z],s="string"==typeof i?JSON.parse(i):i??{locations:{}},a={...s.locations??{}};for(const[e,t]of Object.entries(n.locations))a[e]={...N,...s.locations?.[e]??{},...t};const c={locations:a,...void 0!==s.name_mirror_claims?{name_mirror_claims:s.name_mirror_claims}:{}};await r("directus_settings").update({[Z]:JSON.stringify(c)}),Pe(),t.json({data:{locations:c.locations}})}catch(e){n(e)}}),e.delete("/settings/locations/:location",async(e,t,n)=>{try{if(!lt(e,t))return;const n=String(e.params.location),o=await r("directus_settings").select(Z).first(),i=o?.[Z],s="string"==typeof i?JSON.parse(i):i??{locations:{}};delete s.locations[n],await r("directus_settings").update({[Z]:JSON.stringify(s)}),Pe(),t.json({data:s})}catch(e){n(e)}})}};var pt={id:"storage-manager-operation",handler:async(e,{env:t,database:n,logger:r})=>{const o="copy"===e.mode?"copy":"move",i=String(e.target_storage||"").trim();if(!i)throw new Error("target_storage is required");const s=x(t);if(!s.includes(i))throw new Error(`Unknown target storage "${i}". 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"),o=new Map;for(const e of r){const t=null==e.parent?null:String(e.parent),n=String(e.id);o.has(t)||o.set(t,[]),o.get(t).push(n)}const i=[],s=[String(t)];for(;s.length;){const e=s.pop();i.push(e);for(const t of o.get(e)||[])s.push(t)}return i}(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] ${o} ${a.length} file(s) → ${i}`),await ge({fileIds:a,targetStorage:i,mode:o,concurrency:c,database:n,logger:r})}};const gt=["interface","display","layout","module","panel","theme"],ht=["hook","endpoint"],mt=["operation"];function yt(e,t,n){function r(n,r){var o;Object.defineProperty(n,"_zod",{value:n._zod??{},enumerable:!1}),(o=n._zod).traits??(o.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 o=n?.Parent??Object;class i extends o{}function s(e){var t;const o=n?.Parent?new i:this;r(o,e),(t=o._zod).deferred??(t.deferred=[]);for(const e of o._zod.deferred)e();return o}return Object.defineProperty(i,"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 _t extends Error{constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}}class wt extends Error{constructor(e){super(`Encountered unidirectional transform during encode: ${e}`),this.name="ZodEncodeError"}}const vt={};function kt(e){return vt}function bt(e,t){return"bigint"==typeof t?t.toString():t}function St(e){return{get value(){{const t=e();return Object.defineProperty(this,"value",{value:t}),t}}}}function $t(e){return null==e}function zt(e){const t=e.startsWith("^")?1:0,n=e.endsWith("$")?e.length-1:e.length;return e.slice(t,n)}const jt=Symbol("evaluating");function xt(e,t,n){let r;Object.defineProperty(e,t,{get(){if(r!==jt)return void 0===r&&(r=jt,r=n()),r},set(n){Object.defineProperty(e,t,{value:n})},configurable:!0})}function Et(e,t,n){Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0})}function At(...e){const t={};for(const n of e){const e=Object.getOwnPropertyDescriptors(n);Object.assign(t,e)}return Object.defineProperties({},t)}function Pt(e){return JSON.stringify(e)}const Ot="captureStackTrace"in Error?Error.captureStackTrace:(...e)=>{};function It(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}const Zt=St(()=>{if("undefined"!=typeof navigator&&navigator?.userAgent?.includes("Cloudflare"))return!1;try{return new Function(""),!0}catch(e){return!1}});function Tt(e){if(!1===It(e))return!1;const t=e.constructor;if(void 0===t)return!0;const n=t.prototype;return!1!==It(n)&&!1!==Object.prototype.hasOwnProperty.call(n,"isPrototypeOf")}function Nt(e){return Tt(e)?{...e}:Array.isArray(e)?[...e]:e}const Ft=new Set(["string","number","symbol"]);function Ct(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Dt(e,t,n){const r=new e._zod.constr(t??e._zod.def);return t&&!n?.parent||(r._zod.parent=e),r}function Ut(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 Bt(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 Mt(e,t){return t.map(t=>{var n;return(n=t).path??(n.path=[]),t.path.unshift(e),t})}function Rt(e){return"string"==typeof e?e:e?.message}function Wt(e,t,n){const r={...e,path:e.path??[]};if(!e.message){const o=Rt(e.inst?._zod.def?.error?.(e))??Rt(t?.error?.(e))??Rt(n.customError?.(e))??Rt(n.localeError?.(e))??"Invalid input";r.message=o}return delete r.inst,delete r.continue,t?.reportInput||delete r.input,r}function qt(e){return Array.isArray(e)?"array":"string"==typeof e?"string":"unknown"}function Lt(...e){const[t,n,r]=e;return"string"==typeof t?{message:t,code:"custom",input:n,inst:r}:{...t}}const Jt=(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,bt,2),Object.defineProperty(e,"toString",{value:()=>e.message,enumerable:!1})},Vt=yt("$ZodError",Jt),Gt=yt("$ZodError",Jt,{Parent:Error});const Ht=e=>(t,n,r,o)=>{const i=r?Object.assign(r,{async:!1}):{async:!1},s=t._zod.run({value:n,issues:[]},i);if(s instanceof Promise)throw new _t;if(s.issues.length){const t=new(o?.Err??e)(s.issues.map(e=>Wt(e,i,kt())));throw Ot(t,o?.callee),t}return s.value},Kt=e=>async(t,n,r,o)=>{const i=r?Object.assign(r,{async:!0}):{async:!0};let s=t._zod.run({value:n,issues:[]},i);if(s instanceof Promise&&(s=await s),s.issues.length){const t=new(o?.Err??e)(s.issues.map(e=>Wt(e,i,kt())));throw Ot(t,o?.callee),t}return s.value},Xt=e=>(t,n,r)=>{const o=r?{...r,async:!1}:{async:!1},i=t._zod.run({value:n,issues:[]},o);if(i instanceof Promise)throw new _t;return i.issues.length?{success:!1,error:new(e??Vt)(i.issues.map(e=>Wt(e,o,kt())))}:{success:!0,data:i.value}},Yt=Xt(Gt),Qt=e=>async(t,n,r)=>{const o=r?Object.assign(r,{async:!0}):{async:!0};let i=t._zod.run({value:n,issues:[]},o);return i instanceof Promise&&(i=await i),i.issues.length?{success:!1,error:new e(i.issues.map(e=>Wt(e,o,kt())))}:{success:!0,data:i.value}},en=Qt(Gt),tn=e=>(t,n,r)=>{const o=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Ht(e)(t,n,o)},nn=e=>(t,n,r)=>Ht(e)(t,n,r),rn=e=>async(t,n,r)=>{const o=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Kt(e)(t,n,o)},on=e=>async(t,n,r)=>Kt(e)(t,n,r),sn=e=>(t,n,r)=>{const o=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Xt(e)(t,n,o)},an=e=>(t,n,r)=>Xt(e)(t,n,r),cn=e=>async(t,n,r)=>{const o=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Qt(e)(t,n,o)},ln=e=>async(t,n,r)=>Qt(e)(t,n,r),un=/^[cC][^\s-]{8,}$/,dn=/^[0-9a-z]+$/,fn=/^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/,pn=/^[0-9a-vA-V]{20}$/,gn=/^[A-Za-z0-9]{27}$/,hn=/^[a-zA-Z0-9_-]{21}$/,mn=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/,yn=/^([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})$/,_n=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)$/,wn=/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/;const vn=/^(?:(?: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])$/,kn=/^(([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}|:))$/,bn=/^((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])$/,Sn=/^(([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])$/,$n=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,zn=/^[A-Za-z0-9_-]*$/,jn=/^(?=.{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])?)*\.?$/,xn=/^\+(?:[0-9]){6,14}[0-9]$/,En="(?:(?:\\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])))",An=new RegExp(`^${En}$`);function Pn(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 On=/^(?:true|false)$/i,In=/^[^A-Z]*$/,Zn=/^[^a-z]*$/,Tn=yt("$ZodCheck",(e,t)=>{var n;e._zod??(e._zod={}),e._zod.def=t,(n=e._zod).onattach??(n.onattach=[])}),Nn=yt("$ZodCheckMaxLength",(e,t)=>{var n;Tn.init(e,t),(n=e._zod.def).when??(n.when=e=>{const t=e.value;return!$t(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 o=qt(r);n.issues.push({origin:o,code:"too_big",maximum:t.maximum,inclusive:!0,input:r,inst:e,continue:!t.abort})}}),Fn=yt("$ZodCheckMinLength",(e,t)=>{var n;Tn.init(e,t),(n=e._zod.def).when??(n.when=e=>{const t=e.value;return!$t(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 o=qt(r);n.issues.push({origin:o,code:"too_small",minimum:t.minimum,inclusive:!0,input:r,inst:e,continue:!t.abort})}}),Cn=yt("$ZodCheckLengthEquals",(e,t)=>{var n;Tn.init(e,t),(n=e._zod.def).when??(n.when=e=>{const t=e.value;return!$t(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,o=r.length;if(o===t.length)return;const i=qt(r),s=o>t.length;n.issues.push({origin:i,...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})}}),Dn=yt("$ZodCheckStringFormat",(e,t)=>{var n,r;Tn.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=()=>{})}),Un=yt("$ZodCheckRegex",(e,t)=>{Dn.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})}}),Bn=yt("$ZodCheckLowerCase",(e,t)=>{t.pattern??(t.pattern=In),Dn.init(e,t)}),Mn=yt("$ZodCheckUpperCase",(e,t)=>{t.pattern??(t.pattern=Zn),Dn.init(e,t)}),Rn=yt("$ZodCheckIncludes",(e,t)=>{Tn.init(e,t);const n=Ct(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})}}),Wn=yt("$ZodCheckStartsWith",(e,t)=>{Tn.init(e,t);const n=new RegExp(`^${Ct(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})}}),qn=yt("$ZodCheckEndsWith",(e,t)=>{Tn.init(e,t);const n=new RegExp(`.*${Ct(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})}}),Ln=yt("$ZodCheckOverwrite",(e,t)=>{Tn.init(e,t),e._zod.check=e=>{e.value=t.tx(e.value)}});class Jn{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 Vn={major:4,minor:1,patch:12},Gn=yt("$ZodType",(e,t)=>{var n;e??(e={}),e._zod.def=t,e._zod.bag=e._zod.bag||{},e._zod.version=Vn;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,o=Bt(e);for(const i of t){if(i._zod.def.when){if(!i._zod.def.when(e))continue}else if(o)continue;const t=e.issues.length,s=i._zod.check(e);if(s instanceof Promise&&!1===n?.async)throw new _t;if(r||s instanceof Promise)r=(r??Promise.resolve()).then(async()=>{await s;e.issues.length!==t&&(o||(o=Bt(e,t)))});else{if(e.issues.length===t)continue;o||(o=Bt(e,t))}}return r?r.then(()=>e):e},n=(n,o,i)=>{if(Bt(n))return n.aborted=!0,n;const s=t(o,r,i);if(s instanceof Promise){if(!1===i.async)throw new _t;return s.then(t=>e._zod.parse(t,i))}return e._zod.parse(s,i)};e._zod.run=(o,i)=>{if(i.skipChecks)return e._zod.parse(o,i);if("backward"===i.direction){const t=e._zod.parse({value:o.value,issues:[]},{...i,skipChecks:!0});return t instanceof Promise?t.then(e=>n(e,o,i)):n(t,o,i)}const s=e._zod.parse(o,i);if(s instanceof Promise){if(!1===i.async)throw new _t;return s.then(e=>t(e,r,i))}return t(s,r,i)}}e["~standard"]={validate:t=>{try{const n=Yt(e,t);return n.success?{value:n.data}:{issues:n.error?.issues}}catch(n){return en(e,t).then(e=>e.success?{value:e.data}:{issues:e.error?.issues})}},vendor:"zod",version:1}}),Hn=yt("$ZodString",(e,t)=>{var n;Gn.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}}),Kn=yt("$ZodStringFormat",(e,t)=>{Dn.init(e,t),Hn.init(e,t)}),Xn=yt("$ZodGUID",(e,t)=>{t.pattern??(t.pattern=yn),Kn.init(e,t)}),Yn=yt("$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=_n(e))}else t.pattern??(t.pattern=_n());Kn.init(e,t)}),Qn=yt("$ZodEmail",(e,t)=>{t.pattern??(t.pattern=wn),Kn.init(e,t)}),er=yt("$ZodURL",(e,t)=>{Kn.init(e,t),e._zod.check=n=>{try{const r=n.value.trim(),o=new URL(r);return t.hostname&&(t.hostname.lastIndex=0,t.hostname.test(o.hostname)||n.issues.push({code:"invalid_format",format:"url",note:"Invalid hostname",pattern:jn.source,input:n.value,inst:e,continue:!t.abort})),t.protocol&&(t.protocol.lastIndex=0,t.protocol.test(o.protocol.endsWith(":")?o.protocol.slice(0,-1):o.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=o.href:n.value=r)}catch(r){n.issues.push({code:"invalid_format",format:"url",input:n.value,inst:e,continue:!t.abort})}}}),tr=yt("$ZodEmoji",(e,t)=>{t.pattern??(t.pattern=new RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$","u")),Kn.init(e,t)}),nr=yt("$ZodNanoID",(e,t)=>{t.pattern??(t.pattern=hn),Kn.init(e,t)}),rr=yt("$ZodCUID",(e,t)=>{t.pattern??(t.pattern=un),Kn.init(e,t)}),or=yt("$ZodCUID2",(e,t)=>{t.pattern??(t.pattern=dn),Kn.init(e,t)}),ir=yt("$ZodULID",(e,t)=>{t.pattern??(t.pattern=fn),Kn.init(e,t)}),sr=yt("$ZodXID",(e,t)=>{t.pattern??(t.pattern=pn),Kn.init(e,t)}),ar=yt("$ZodKSUID",(e,t)=>{t.pattern??(t.pattern=gn),Kn.init(e,t)}),cr=yt("$ZodISODateTime",(e,t)=>{t.pattern??(t.pattern=function(e){const t=Pn({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(`^${En}T(?:${r})$`)}(t)),Kn.init(e,t)}),lr=yt("$ZodISODate",(e,t)=>{t.pattern??(t.pattern=An),Kn.init(e,t)}),ur=yt("$ZodISOTime",(e,t)=>{t.pattern??(t.pattern=new RegExp(`^${Pn(t)}$`)),Kn.init(e,t)}),dr=yt("$ZodISODuration",(e,t)=>{t.pattern??(t.pattern=mn),Kn.init(e,t)}),fr=yt("$ZodIPv4",(e,t)=>{t.pattern??(t.pattern=vn),Kn.init(e,t),e._zod.onattach.push(e=>{e._zod.bag.format="ipv4"})}),pr=yt("$ZodIPv6",(e,t)=>{t.pattern??(t.pattern=kn),Kn.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})}}}),gr=yt("$ZodCIDRv4",(e,t)=>{t.pattern??(t.pattern=bn),Kn.init(e,t)}),hr=yt("$ZodCIDRv6",(e,t)=>{t.pattern??(t.pattern=Sn),Kn.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 mr(e){if(""===e)return!0;if(e.length%4!=0)return!1;try{return atob(e),!0}catch{return!1}}const yr=yt("$ZodBase64",(e,t)=>{t.pattern??(t.pattern=$n),Kn.init(e,t),e._zod.onattach.push(e=>{e._zod.bag.contentEncoding="base64"}),e._zod.check=n=>{mr(n.value)||n.issues.push({code:"invalid_format",format:"base64",input:n.value,inst:e,continue:!t.abort})}});const _r=yt("$ZodBase64URL",(e,t)=>{t.pattern??(t.pattern=zn),Kn.init(e,t),e._zod.onattach.push(e=>{e._zod.bag.contentEncoding="base64url"}),e._zod.check=n=>{(function(e){if(!zn.test(e))return!1;const t=e.replace(/[-_]/g,e=>"-"===e?"+":"/");return mr(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})}}),wr=yt("$ZodE164",(e,t)=>{t.pattern??(t.pattern=xn),Kn.init(e,t)});const vr=yt("$ZodJWT",(e,t)=>{Kn.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 o=JSON.parse(atob(r));return!("typ"in o&&"JWT"!==o?.typ||!o.alg||t&&(!("alg"in o)||o.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})}}),kr=yt("$ZodBoolean",(e,t)=>{Gn.init(e,t),e._zod.pattern=On,e._zod.parse=(n,r)=>{if(t.coerce)try{n.value=Boolean(n.value)}catch(e){}const o=n.value;return"boolean"==typeof o||n.issues.push({expected:"boolean",code:"invalid_type",input:o,inst:e}),n}}),br=yt("$ZodUnknown",(e,t)=>{Gn.init(e,t),e._zod.parse=e=>e}),Sr=yt("$ZodNever",(e,t)=>{Gn.init(e,t),e._zod.parse=(t,n)=>(t.issues.push({expected:"never",code:"invalid_type",input:t.value,inst:e}),t)});function $r(e,t,n){e.issues.length&&t.issues.push(...Mt(n,e.issues)),t.value[n]=e.value}const zr=yt("$ZodArray",(e,t)=>{Gn.init(e,t),e._zod.parse=(n,r)=>{const o=n.value;if(!Array.isArray(o))return n.issues.push({expected:"array",code:"invalid_type",input:o,inst:e}),n;n.value=Array(o.length);const i=[];for(let e=0;e<o.length;e++){const s=o[e],a=t.element._zod.run({value:s,issues:[]},r);a instanceof Promise?i.push(a.then(t=>$r(t,n,e))):$r(a,n,e)}return i.length?Promise.all(i).then(()=>n):n}});function jr(e,t,n,r){e.issues.length&&t.issues.push(...Mt(n,e.issues)),void 0===e.value?n in r&&(t.value[n]=void 0):t.value[n]=e.value}function xr(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 Er(e,t,n,r,o,i){const s=[],a=o.keySet,c=o.catchall._zod,l=c.def.type;for(const o of Object.keys(t)){if(a.has(o))continue;if("never"===l){s.push(o);continue}const i=c.run({value:t[o],issues:[]},r);i instanceof Promise?e.push(i.then(e=>jr(e,n,o,t))):jr(i,n,o,t)}return s.length&&n.issues.push({code:"unrecognized_keys",keys:s,input:t,inst:i}),e.length?Promise.all(e).then(()=>n):n}const Ar=yt("$ZodObject",(e,t)=>{Gn.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=St(()=>xr(t));xt(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 o=It,i=t.catchall;let s;e._zod.parse=(t,n)=>{s??(s=r.value);const a=t.value;if(!o(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=>jr(n,t,e,a))):jr(r,t,e,a)}return i?Er(c,a,t,n,r.value,e):c.length?Promise.all(c).then(()=>t):t}}),Pr=yt("$ZodObjectJIT",(e,t)=>{Ar.init(e,t);const n=e._zod.parse,r=St(()=>xr(t));let o;const i=It,s=!vt.jitless,a=s&&Zt.value,c=t.catchall;let l;e._zod.parse=(u,d)=>{l??(l=r.value);const f=u.value;return i(f)?s&&a&&!1===d?.async&&!0!==d.jitless?(o||(o=(e=>{const t=new Jn(["shape","payload","ctx"]),n=r.value,o=e=>{const t=Pt(e);return`shape[${t}]._zod.run({ value: input[${t}], issues: [] }, ctx)`};t.write("const input = payload.value;");const i=Object.create(null);let s=0;for(const e of n.keys)i[e]="key_"+s++;t.write("const newResult = {};");for(const e of n.keys){const n=i[e],r=Pt(e);t.write(`const ${n} = ${o(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=o(u,d),c?Er([],f,u,d,l,e):u):n(u,d):(u.issues.push({expected:"object",code:"invalid_type",input:f,inst:e}),u)}});function Or(e,t,n,r){for(const n of e)if(0===n.issues.length)return t.value=n.value,t;const o=e.filter(e=>!Bt(e));return 1===o.length?(t.value=o[0].value,o[0]):(t.issues.push({code:"invalid_union",input:t.value,inst:n,errors:e.map(e=>e.issues.map(e=>Wt(e,r,kt())))}),t)}const Ir=yt("$ZodUnion",(e,t)=>{Gn.init(e,t),xt(e._zod,"optin",()=>t.options.some(e=>"optional"===e._zod.optin)?"optional":void 0),xt(e._zod,"optout",()=>t.options.some(e=>"optional"===e._zod.optout)?"optional":void 0),xt(e._zod,"values",()=>{if(t.options.every(e=>e._zod.values))return new Set(t.options.flatMap(e=>Array.from(e._zod.values)))}),xt(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=>zt(e.source)).join("|")})$`)}});const n=1===t.options.length,r=t.options[0]._zod.run;e._zod.parse=(o,i)=>{if(n)return r(o,i);let s=!1;const a=[];for(const e of t.options){const t=e._zod.run({value:o.value,issues:[]},i);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=>Or(t,o,e,i)):Or(a,o,e,i)}}),Zr=yt("$ZodIntersection",(e,t)=>{Gn.init(e,t),e._zod.parse=(e,n)=>{const r=e.value,o=t.left._zod.run({value:r,issues:[]},n),i=t.right._zod.run({value:r,issues:[]},n);return o instanceof Promise||i instanceof Promise?Promise.all([o,i]).then(([t,n])=>Nr(e,t,n)):Nr(e,o,i)}});function Tr(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(Tt(e)&&Tt(t)){const n=Object.keys(t),r=Object.keys(e).filter(e=>-1!==n.indexOf(e)),o={...e,...t};for(const n of r){const r=Tr(e[n],t[n]);if(!r.valid)return{valid:!1,mergeErrorPath:[n,...r.mergeErrorPath]};o[n]=r.data}return{valid:!0,data:o}}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 o=Tr(e[r],t[r]);if(!o.valid)return{valid:!1,mergeErrorPath:[r,...o.mergeErrorPath]};n.push(o.data)}return{valid:!0,data:n}}return{valid:!1,mergeErrorPath:[]}}function Nr(e,t,n){if(t.issues.length&&e.issues.push(...t.issues),n.issues.length&&e.issues.push(...n.issues),Bt(e))return e;const r=Tr(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 Fr=yt("$ZodRecord",(e,t)=>{Gn.init(e,t),e._zod.parse=(n,r)=>{const o=n.value;if(!Tt(o))return n.issues.push({expected:"record",code:"invalid_type",input:o,inst:e}),n;const i=[];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:o[e],issues:[]},r);s instanceof Promise?i.push(s.then(t=>{t.issues.length&&n.issues.push(...Mt(e,t.issues)),n.value[e]=t.value})):(s.issues.length&&n.issues.push(...Mt(e,s.issues)),n.value[e]=s.value)}let a;for(const e in o)s.has(e)||(a=a??[],a.push(e));a&&a.length>0&&n.issues.push({code:"unrecognized_keys",input:o,inst:e,keys:a})}else{n.value={};for(const s of Reflect.ownKeys(o)){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=>Wt(e,r,kt())),input:s,path:[s],inst:e}),n.value[a.value]=a.value;continue}const c=t.valueType._zod.run({value:o[s],issues:[]},r);c instanceof Promise?i.push(c.then(e=>{e.issues.length&&n.issues.push(...Mt(s,e.issues)),n.value[a.value]=e.value})):(c.issues.length&&n.issues.push(...Mt(s,c.issues)),n.value[a.value]=c.value)}}return i.length?Promise.all(i).then(()=>n):n}}),Cr=yt("$ZodEnum",(e,t)=>{Gn.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=>Ft.has(typeof e)).map(e=>"string"==typeof e?Ct(e):e.toString()).join("|")})$`),e._zod.parse=(t,o)=>{const i=t.value;return r.has(i)||t.issues.push({code:"invalid_value",values:n,input:i,inst:e}),t}}),Dr=yt("$ZodLiteral",(e,t)=>{if(Gn.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?Ct(e):e?Ct(e.toString()):String(e)).join("|")})$`),e._zod.parse=(n,r)=>{const o=n.value;return e._zod.values.has(o)||n.issues.push({code:"invalid_value",values:t.values,input:o,inst:e}),n}}),Ur=yt("$ZodTransform",(e,t)=>{Gn.init(e,t),e._zod.parse=(n,r)=>{if("backward"===r.direction)throw new wt(e.constructor.name);const o=t.transform(n.value,n);if(r.async){return(o instanceof Promise?o:Promise.resolve(o)).then(e=>(n.value=e,n))}if(o instanceof Promise)throw new _t;return n.value=o,n}});function Br(e,t){return e.issues.length&&void 0===t?{issues:[],value:void 0}:e}const Mr=yt("$ZodOptional",(e,t)=>{Gn.init(e,t),e._zod.optin="optional",e._zod.optout="optional",xt(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),xt(e._zod,"pattern",()=>{const e=t.innerType._zod.pattern;return e?new RegExp(`^(${zt(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=>Br(t,e.value)):Br(r,e.value)}return void 0===e.value?e:t.innerType._zod.run(e,n)}}),Rr=yt("$ZodNullable",(e,t)=>{Gn.init(e,t),xt(e._zod,"optin",()=>t.innerType._zod.optin),xt(e._zod,"optout",()=>t.innerType._zod.optout),xt(e._zod,"pattern",()=>{const e=t.innerType._zod.pattern;return e?new RegExp(`^(${zt(e.source)}|null)$`):void 0}),xt(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)}),Wr=yt("$ZodDefault",(e,t)=>{Gn.init(e,t),e._zod.optin="optional",xt(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=>qr(e,t)):qr(r,t)}});function qr(e,t){return void 0===e.value&&(e.value=t.defaultValue),e}const Lr=yt("$ZodPrefault",(e,t)=>{Gn.init(e,t),e._zod.optin="optional",xt(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))}),Jr=yt("$ZodNonOptional",(e,t)=>{Gn.init(e,t),xt(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 o=t.innerType._zod.run(n,r);return o instanceof Promise?o.then(t=>Vr(t,e)):Vr(o,e)}});function Vr(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 Gr=yt("$ZodCatch",(e,t)=>{Gn.init(e,t),xt(e._zod,"optin",()=>t.innerType._zod.optin),xt(e._zod,"optout",()=>t.innerType._zod.optout),xt(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=>Wt(e,n,kt()))},input:e.value}),e.issues=[]),e)):(e.value=r.value,r.issues.length&&(e.value=t.catchValue({...e,error:{issues:r.issues.map(e=>Wt(e,n,kt()))},input:e.value}),e.issues=[]),e)}}),Hr=yt("$ZodPipe",(e,t)=>{Gn.init(e,t),xt(e._zod,"values",()=>t.in._zod.values),xt(e._zod,"optin",()=>t.in._zod.optin),xt(e._zod,"optout",()=>t.out._zod.optout),xt(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=>Kr(e,t.in,n)):Kr(r,t.in,n)}const r=t.in._zod.run(e,n);return r instanceof Promise?r.then(e=>Kr(e,t.out,n)):Kr(r,t.out,n)}});function Kr(e,t,n){return e.issues.length?(e.aborted=!0,e):t._zod.run({value:e.value,issues:e.issues},n)}const Xr=yt("$ZodReadonly",(e,t)=>{Gn.init(e,t),xt(e._zod,"propValues",()=>t.innerType._zod.propValues),xt(e._zod,"values",()=>t.innerType._zod.values),xt(e._zod,"optin",()=>t.innerType._zod.optin),xt(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(Yr):Yr(r)}});function Yr(e){return e.value=Object.freeze(e.value),e}const Qr=yt("$ZodCustom",(e,t)=>{Tn.init(e,t),Gn.init(e,t),e._zod.parse=(e,t)=>e,e._zod.check=n=>{const r=n.value,o=t.fn(r);if(o instanceof Promise)return o.then(t=>eo(t,n,r,e));eo(o,n,r,e)}});function eo(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(Lt(e))}}class to{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 no(){return new to}const ro=no();function oo(e,t){return new e({type:"string",format:"guid",check:"string_format",abort:!1,...Ut(t)})}function io(e,t){return new Nn({check:"max_length",...Ut(t),maximum:e})}function so(e,t){return new Fn({check:"min_length",...Ut(t),minimum:e})}function ao(e,t){return new Cn({check:"length_equals",...Ut(t),length:e})}function co(e){return new Ln({check:"overwrite",tx:e})}function lo(e){const t=function(e,t){const n=new Tn({check:"custom",...Ut(t)});return n._zod.check=e,n}(n=>(n.addIssue=e=>{if("string"==typeof e)n.issues.push(Lt(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(Lt(r))}},e(n.value,n)));return t}const uo=yt("ZodISODateTime",(e,t)=>{cr.init(e,t),Fo.init(e,t)});function fo(e){return function(e,t){return new e({type:"string",format:"datetime",check:"string_format",offset:!1,local:!1,precision:null,...Ut(t)})}(uo,e)}const po=yt("ZodISODate",(e,t)=>{lr.init(e,t),Fo.init(e,t)});function go(e){return function(e,t){return new e({type:"string",format:"date",check:"string_format",...Ut(t)})}(po,e)}const ho=yt("ZodISOTime",(e,t)=>{ur.init(e,t),Fo.init(e,t)});function mo(e){return function(e,t){return new e({type:"string",format:"time",check:"string_format",precision:null,...Ut(t)})}(ho,e)}const yo=yt("ZodISODuration",(e,t)=>{dr.init(e,t),Fo.init(e,t)});function _o(e){return function(e,t){return new e({type:"string",format:"duration",check:"string_format",...Ut(t)})}(yo,e)}const wo=yt("ZodError",(e,t)=>{Vt.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 o of e.issues)if("invalid_union"===o.code&&o.errors.length)o.errors.map(e=>r({issues:e}));else if("invalid_key"===o.code)r({issues:o.issues});else if("invalid_element"===o.code)r({issues:o.issues});else if(0===o.path.length)n._errors.push(t(o));else{let e=n,r=0;for(;r<o.path.length;){const n=o.path[r];r===o.path.length-1?(e[n]=e[n]||{_errors:[]},e[n]._errors.push(t(o))):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 o of e.issues)o.path.length>0?(n[o.path[0]]=n[o.path[0]]||[],n[o.path[0]].push(t(o))):r.push(t(o));return{formErrors:r,fieldErrors:n}}(e,t)},addIssue:{value:t=>{e.issues.push(t),e.message=JSON.stringify(e.issues,bt,2)}},addIssues:{value:t=>{e.issues.push(...t),e.message=JSON.stringify(e.issues,bt,2)}},isEmpty:{get:()=>0===e.issues.length}})},{Parent:Error}),vo=Ht(wo),ko=Kt(wo),bo=Xt(wo),So=Qt(wo),$o=tn(wo),zo=nn(wo),jo=rn(wo),xo=on(wo),Eo=sn(wo),Ao=an(wo),Po=cn(wo),Oo=ln(wo),Io=yt("ZodType",(e,t)=>(Gn.init(e,t),e.def=t,e.type=t.type,Object.defineProperty(e,"_def",{value:t}),e.check=(...n)=>e.clone(At(t,{checks:[...t.checks??[],...n.map(e=>"function"==typeof e?{_zod:{check:e,def:{check:"custom"},onattach:[]}}:e)]})),e.clone=(t,n)=>Dt(e,t,n),e.brand=()=>e,e.register=(t,n)=>(t.add(e,n),e),e.parse=(t,n)=>vo(e,t,n,{callee:e.parse}),e.safeParse=(t,n)=>bo(e,t,n),e.parseAsync=async(t,n)=>ko(e,t,n,{callee:e.parseAsync}),e.safeParseAsync=async(t,n)=>So(e,t,n),e.spa=e.safeParseAsync,e.encode=(t,n)=>$o(e,t,n),e.decode=(t,n)=>zo(e,t,n),e.encodeAsync=async(t,n)=>jo(e,t,n),e.decodeAsync=async(t,n)=>xo(e,t,n),e.safeEncode=(t,n)=>Eo(e,t,n),e.safeDecode=(t,n)=>Ao(e,t,n),e.safeEncodeAsync=async(t,n)=>Po(e,t,n),e.safeDecodeAsync=async(t,n)=>Oo(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,...Ut(n)})}(Zi,e,t)}(t,n)),e.superRefine=t=>e.check(lo(t)),e.overwrite=t=>e.check(co(t)),e.optional=()=>Si(e),e.nullable=()=>zi(e),e.nullish=()=>Si(zi(e)),e.nonoptional=t=>function(e,t){return new Ei({type:"nonoptional",innerType:e,...Ut(t)})}(e,t),e.array=()=>li(e),e.or=t=>pi([e,t]),e.and=t=>new gi({type:"intersection",left:e,right:t}),e.transform=t=>Oi(e,new ki({type:"transform",transform:t})),e.default=t=>{return n=t,new ji({type:"default",innerType:e,get defaultValue(){return"function"==typeof n?n():Nt(n)}});var n},e.prefault=t=>{return n=t,new xi({type:"prefault",innerType:e,get defaultValue(){return"function"==typeof n?n():Nt(n)}});var n},e.catch=t=>{return new Ai({type:"catch",innerType:e,catchValue:"function"==typeof(n=t)?n:()=>n});var n},e.pipe=t=>Oi(e,t),e.readonly=()=>new Ii({type:"readonly",innerType:e}),e.describe=t=>{const n=e.clone();return ro.add(n,{description:t}),n},Object.defineProperty(e,"description",{get:()=>ro.get(e)?.description,configurable:!0}),e.meta=(...t)=>{if(0===t.length)return ro.get(e);const n=e.clone();return ro.add(n,t[0]),n},e.isOptional=()=>e.safeParse(void 0).success,e.isNullable=()=>e.safeParse(null).success,e)),Zo=yt("_ZodString",(e,t)=>{Hn.init(e,t),Io.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 Un({check:"string_format",format:"regex",...Ut(t),pattern:e})}(...t)),e.includes=(...t)=>e.check(function(e,t){return new Rn({check:"string_format",format:"includes",...Ut(t),includes:e})}(...t)),e.startsWith=(...t)=>e.check(function(e,t){return new Wn({check:"string_format",format:"starts_with",...Ut(t),prefix:e})}(...t)),e.endsWith=(...t)=>e.check(function(e,t){return new qn({check:"string_format",format:"ends_with",...Ut(t),suffix:e})}(...t)),e.min=(...t)=>e.check(so(...t)),e.max=(...t)=>e.check(io(...t)),e.length=(...t)=>e.check(ao(...t)),e.nonempty=(...t)=>e.check(so(1,...t)),e.lowercase=t=>e.check(function(e){return new Bn({check:"string_format",format:"lowercase",...Ut(e)})}(t)),e.uppercase=t=>e.check(function(e){return new Mn({check:"string_format",format:"uppercase",...Ut(e)})}(t)),e.trim=()=>e.check(co(e=>e.trim())),e.normalize=(...t)=>e.check(function(e){return co(t=>t.normalize(e))}(...t)),e.toLowerCase=()=>e.check(co(e=>e.toLowerCase())),e.toUpperCase=()=>e.check(co(e=>e.toUpperCase()))}),To=yt("ZodString",(e,t)=>{Hn.init(e,t),Zo.init(e,t),e.email=t=>e.check(function(e,t){return new e({type:"string",format:"email",check:"string_format",abort:!1,...Ut(t)})}(Co,t)),e.url=t=>e.check(function(e,t){return new e({type:"string",format:"url",check:"string_format",abort:!1,...Ut(t)})}(Bo,t)),e.jwt=t=>e.check(function(e,t){return new e({type:"string",format:"jwt",check:"string_format",abort:!1,...Ut(t)})}(ti,t)),e.emoji=t=>e.check(function(e,t){return new e({type:"string",format:"emoji",check:"string_format",abort:!1,...Ut(t)})}(Mo,t)),e.guid=t=>e.check(oo(Do,t)),e.uuid=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,...Ut(t)})}(Uo,t)),e.uuidv4=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v4",...Ut(t)})}(Uo,t)),e.uuidv6=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v6",...Ut(t)})}(Uo,t)),e.uuidv7=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v7",...Ut(t)})}(Uo,t)),e.nanoid=t=>e.check(function(e,t){return new e({type:"string",format:"nanoid",check:"string_format",abort:!1,...Ut(t)})}(Ro,t)),e.guid=t=>e.check(oo(Do,t)),e.cuid=t=>e.check(function(e,t){return new e({type:"string",format:"cuid",check:"string_format",abort:!1,...Ut(t)})}(Wo,t)),e.cuid2=t=>e.check(function(e,t){return new e({type:"string",format:"cuid2",check:"string_format",abort:!1,...Ut(t)})}(qo,t)),e.ulid=t=>e.check(function(e,t){return new e({type:"string",format:"ulid",check:"string_format",abort:!1,...Ut(t)})}(Lo,t)),e.base64=t=>e.check(function(e,t){return new e({type:"string",format:"base64",check:"string_format",abort:!1,...Ut(t)})}(Yo,t)),e.base64url=t=>e.check(function(e,t){return new e({type:"string",format:"base64url",check:"string_format",abort:!1,...Ut(t)})}(Qo,t)),e.xid=t=>e.check(function(e,t){return new e({type:"string",format:"xid",check:"string_format",abort:!1,...Ut(t)})}(Jo,t)),e.ksuid=t=>e.check(function(e,t){return new e({type:"string",format:"ksuid",check:"string_format",abort:!1,...Ut(t)})}(Vo,t)),e.ipv4=t=>e.check(function(e,t){return new e({type:"string",format:"ipv4",check:"string_format",abort:!1,...Ut(t)})}(Go,t)),e.ipv6=t=>e.check(function(e,t){return new e({type:"string",format:"ipv6",check:"string_format",abort:!1,...Ut(t)})}(Ho,t)),e.cidrv4=t=>e.check(function(e,t){return new e({type:"string",format:"cidrv4",check:"string_format",abort:!1,...Ut(t)})}(Ko,t)),e.cidrv6=t=>e.check(function(e,t){return new e({type:"string",format:"cidrv6",check:"string_format",abort:!1,...Ut(t)})}(Xo,t)),e.e164=t=>e.check(function(e,t){return new e({type:"string",format:"e164",check:"string_format",abort:!1,...Ut(t)})}(ei,t)),e.datetime=t=>e.check(fo(t)),e.date=t=>e.check(go(t)),e.time=t=>e.check(mo(t)),e.duration=t=>e.check(_o(t))});function No(e){return function(e,t){return new e({type:"string",...Ut(t)})}(To,e)}const Fo=yt("ZodStringFormat",(e,t)=>{Kn.init(e,t),Zo.init(e,t)}),Co=yt("ZodEmail",(e,t)=>{Qn.init(e,t),Fo.init(e,t)}),Do=yt("ZodGUID",(e,t)=>{Xn.init(e,t),Fo.init(e,t)}),Uo=yt("ZodUUID",(e,t)=>{Yn.init(e,t),Fo.init(e,t)}),Bo=yt("ZodURL",(e,t)=>{er.init(e,t),Fo.init(e,t)}),Mo=yt("ZodEmoji",(e,t)=>{tr.init(e,t),Fo.init(e,t)}),Ro=yt("ZodNanoID",(e,t)=>{nr.init(e,t),Fo.init(e,t)}),Wo=yt("ZodCUID",(e,t)=>{rr.init(e,t),Fo.init(e,t)}),qo=yt("ZodCUID2",(e,t)=>{or.init(e,t),Fo.init(e,t)}),Lo=yt("ZodULID",(e,t)=>{ir.init(e,t),Fo.init(e,t)}),Jo=yt("ZodXID",(e,t)=>{sr.init(e,t),Fo.init(e,t)}),Vo=yt("ZodKSUID",(e,t)=>{ar.init(e,t),Fo.init(e,t)}),Go=yt("ZodIPv4",(e,t)=>{fr.init(e,t),Fo.init(e,t)}),Ho=yt("ZodIPv6",(e,t)=>{pr.init(e,t),Fo.init(e,t)}),Ko=yt("ZodCIDRv4",(e,t)=>{gr.init(e,t),Fo.init(e,t)}),Xo=yt("ZodCIDRv6",(e,t)=>{hr.init(e,t),Fo.init(e,t)}),Yo=yt("ZodBase64",(e,t)=>{yr.init(e,t),Fo.init(e,t)}),Qo=yt("ZodBase64URL",(e,t)=>{_r.init(e,t),Fo.init(e,t)}),ei=yt("ZodE164",(e,t)=>{wr.init(e,t),Fo.init(e,t)}),ti=yt("ZodJWT",(e,t)=>{vr.init(e,t),Fo.init(e,t)}),ni=yt("ZodBoolean",(e,t)=>{kr.init(e,t),Io.init(e,t)});function ri(e){return function(e,t){return new e({type:"boolean",...Ut(t)})}(ni,e)}const oi=yt("ZodUnknown",(e,t)=>{br.init(e,t),Io.init(e,t)});function ii(){return new oi({type:"unknown"})}const si=yt("ZodNever",(e,t)=>{Sr.init(e,t),Io.init(e,t)});function ai(e){return function(e,t){return new e({type:"never",...Ut(t)})}(si,e)}const ci=yt("ZodArray",(e,t)=>{zr.init(e,t),Io.init(e,t),e.element=t.element,e.min=(t,n)=>e.check(so(t,n)),e.nonempty=t=>e.check(so(1,t)),e.max=(t,n)=>e.check(io(t,n)),e.length=(t,n)=>e.check(ao(t,n)),e.unwrap=()=>e.element});function li(e,t){return function(e,t,n){return new e({type:"array",element:t,...Ut(n)})}(ci,e,t)}const ui=yt("ZodObject",(e,t)=>{Pr.init(e,t),Io.init(e,t),xt(e,"shape",()=>t.shape),e.keyof=()=>_i(Object.keys(e._zod.def.shape)),e.catchall=t=>e.clone({...e._zod.def,catchall:t}),e.passthrough=()=>e.clone({...e._zod.def,catchall:ii()}),e.loose=()=>e.clone({...e._zod.def,catchall:ii()}),e.strict=()=>e.clone({...e._zod.def,catchall:ai()}),e.strip=()=>e.clone({...e._zod.def,catchall:void 0}),e.extend=t=>function(e,t){if(!Tt(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=At(e._zod.def,{get shape(){const n={...e._zod.def.shape,...t};return Et(this,"shape",n),n},checks:[]});return Dt(e,r)}(e,t),e.safeExtend=t=>function(e,t){if(!Tt(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 Et(this,"shape",n),n},checks:e._zod.def.checks};return Dt(e,n)}(e,t),e.merge=t=>function(e,t){const n=At(e._zod.def,{get shape(){const n={...e._zod.def.shape,...t._zod.def.shape};return Et(this,"shape",n),n},get catchall(){return t._zod.def.catchall},checks:[]});return Dt(e,n)}(e,t),e.pick=t=>function(e,t){const n=e._zod.def;return Dt(e,At(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 Et(this,"shape",e),e},checks:[]}))}(e,t),e.omit=t=>function(e,t){const n=e._zod.def,r=At(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 Et(this,"shape",r),r},checks:[]});return Dt(e,r)}(e,t),e.partial=(...t)=>function(e,t,n){const r=At(t._zod.def,{get shape(){const r=t._zod.def.shape,o={...r};if(n)for(const t in n){if(!(t in r))throw new Error(`Unrecognized key: "${t}"`);n[t]&&(o[t]=e?new e({type:"optional",innerType:r[t]}):r[t])}else for(const t in r)o[t]=e?new e({type:"optional",innerType:r[t]}):r[t];return Et(this,"shape",o),o},checks:[]});return Dt(t,r)}(bi,e,t[0]),e.required=(...t)=>function(e,t,n){const r=At(t._zod.def,{get shape(){const r=t._zod.def.shape,o={...r};if(n)for(const t in n){if(!(t in o))throw new Error(`Unrecognized key: "${t}"`);n[t]&&(o[t]=new e({type:"nonoptional",innerType:r[t]}))}else for(const t in r)o[t]=new e({type:"nonoptional",innerType:r[t]});return Et(this,"shape",o),o},checks:[]});return Dt(t,r)}(Ei,e,t[0])});function di(e,t){const n={type:"object",shape:e??{},...Ut(t)};return new ui(n)}const fi=yt("ZodUnion",(e,t)=>{Ir.init(e,t),Io.init(e,t),e.options=t.options});function pi(e,t){return new fi({type:"union",options:e,...Ut(t)})}const gi=yt("ZodIntersection",(e,t)=>{Zr.init(e,t),Io.init(e,t)});const hi=yt("ZodRecord",(e,t)=>{Fr.init(e,t),Io.init(e,t),e.keyType=t.keyType,e.valueType=t.valueType});function mi(e,t,n){return new hi({type:"record",keyType:e,valueType:t,...Ut(n)})}const yi=yt("ZodEnum",(e,t)=>{Cr.init(e,t),Io.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 o={};for(const r of e){if(!n.has(r))throw new Error(`Key ${r} not found in enum`);o[r]=t.entries[r]}return new yi({...t,checks:[],...Ut(r),entries:o})},e.exclude=(e,r)=>{const o={...t.entries};for(const t of e){if(!n.has(t))throw new Error(`Key ${t} not found in enum`);delete o[t]}return new yi({...t,checks:[],...Ut(r),entries:o})}});function _i(e,t){const n=Array.isArray(e)?Object.fromEntries(e.map(e=>[e,e])):e;return new yi({type:"enum",entries:n,...Ut(t)})}const wi=yt("ZodLiteral",(e,t)=>{Dr.init(e,t),Io.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 vi(e,t){return new wi({type:"literal",values:Array.isArray(e)?e:[e],...Ut(t)})}const ki=yt("ZodTransform",(e,t)=>{Ur.init(e,t),Io.init(e,t),e._zod.parse=(n,r)=>{if("backward"===r.direction)throw new wt(e.constructor.name);n.addIssue=r=>{if("string"==typeof r)n.issues.push(Lt(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(Lt(t))}};const o=t.transform(n.value,n);return o instanceof Promise?o.then(e=>(n.value=e,n)):(n.value=o,n)}});const bi=yt("ZodOptional",(e,t)=>{Mr.init(e,t),Io.init(e,t),e.unwrap=()=>e._zod.def.innerType});function Si(e){return new bi({type:"optional",innerType:e})}const $i=yt("ZodNullable",(e,t)=>{Rr.init(e,t),Io.init(e,t),e.unwrap=()=>e._zod.def.innerType});function zi(e){return new $i({type:"nullable",innerType:e})}const ji=yt("ZodDefault",(e,t)=>{Wr.init(e,t),Io.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeDefault=e.unwrap});const xi=yt("ZodPrefault",(e,t)=>{Lr.init(e,t),Io.init(e,t),e.unwrap=()=>e._zod.def.innerType});const Ei=yt("ZodNonOptional",(e,t)=>{Jr.init(e,t),Io.init(e,t),e.unwrap=()=>e._zod.def.innerType});const Ai=yt("ZodCatch",(e,t)=>{Gr.init(e,t),Io.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeCatch=e.unwrap});const Pi=yt("ZodPipe",(e,t)=>{Hr.init(e,t),Io.init(e,t),e.in=t.in,e.out=t.out});function Oi(e,t){return new Pi({type:"pipe",in:e,out:t})}const Ii=yt("ZodReadonly",(e,t)=>{Xr.init(e,t),Io.init(e,t),e.unwrap=()=>e._zod.def.innerType});const Zi=yt("ZodCustom",(e,t)=>{Qr.init(e,t),Io.init(e,t)});const Ti="directus:extension",Ni=di({app:No(),api:No()}),Fi=di({request:Si(di({urls:li(No()),methods:li(pi([vi("GET"),vi("POST"),vi("PATCH"),vi("PUT"),vi("DELETE")]))})),log:Si(di({})),sleep:Si(di({}))}),Ci=Si(di({enabled:ri(),requestedScopes:Fi})),Di=pi([di({type:_i(ht),name:No(),source:No()}),di({type:_i(gt),name:No(),source:No()}),di({type:_i(mt),name:No(),source:Ni})]),Ui=di({host:No(),hidden:ri().optional()}),Bi=di({type:_i(gt),path:No(),source:No()}),Mi=di({type:_i(ht),path:No(),source:No(),sandbox:Ci}),Ri=di({type:_i(mt),path:Ni,source:Ni,sandbox:Ci}),Wi=di({type:vi("bundle"),partial:ri().optional(),path:Ni,entries:li(Di)});li(Di);const qi=Ui.and(pi([Bi,Mi,Ri,Wi]));di({name:No(),version:No(),type:pi([vi("module"),vi("commonjs")]).optional(),description:No().optional(),icon:No().optional(),dependencies:mi(No(),No()).optional(),devDependencies:mi(No(),No()).optional(),[Ti]:qi});function Li(e){return Object.entries(e).filter(([,e])=>Je(e)&&qe(e.prefix_strategy)).map(([e])=>e)}async function Ji(e,t,n,r,o){if(n&&n!==r)for(const i of t)try{const t=await e("directus_files").count({c:"*"}).where("storage",i).whereRaw("filename_disk LIKE ?",[`${n}/%`]).first(),s=Number(t?.c??0);s>=100&&o.warn(`[storage-manager] Folder path sync on ${i}: relocating ${s} files (“${n}” → “${r||"(root)"}”) — this may take a while`);const{moved:a,failed:c}=await ce(e,i,n,r,o);(a||c)&&o.info(`[storage-manager] Folder path sync on ${i}: "${n}" → "${r||"(root)"}" (moved=${a}, failed=${c})`)}catch(e){o.error(`[storage-manager] Folder path sync failed for ${i}: ${e?.message}`)}}async function Vi(e,t,n){const r={},o={},i=await t("directus_folders").select("id","parent").where("id",e).first(),s=i?.parent?String(i.parent):null;for(const i of(a=n,Object.entries(a).filter(([,e])=>Je(e)).map(([e])=>e))){const a=n[i];let c=null,l="";qe(a.prefix_strategy)?(c=await Ge(t,e),l=s&&await Ge(t,s)||""):Le(a.prefix_strategy)&&(c=await He(t,e),l=s&&await He(t,s)||""),c&&(r[i]=c,o[i]=l)}var a;return{folderPaths:r,parentPaths:o}}async function Gi(e,t,n){const r=await n("directus_folders").select("id","name","parent").where("id",e).first();if(!r)return null;const o=String(r.name);if(o===t)return null;const i=r.parent?String(r.parent):null,s=new Set([e,...await Ce(n,i,o),...await Ce(n,i,t)]),a={};for(const e of s){const t=await Ge(n,e);t&&(a[e]=t)}return a}async function Hi(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),o=n.parent?String(n.parent):null,i=(await Ce(t,o,r)).filter(t=>t!==e),s={};for(const e of i){const n=await Ge(t,e);n&&(s[e]=n)}return{parent:o,name:r,siblingOldPaths:s}}async function Ki(e,t,n,r,o){const i=Li(r);if(i.length)for(const[e,r]of Object.entries(t)){const t=await Ge(n,e);t&&r&&t!==r&&await Ji(n,i,r,t,o)}}async function Xi(e,t,n,r){const o=Li(n);if(o.length)for(const[n,i]of Object.entries(e)){const e=await Ge(t,n);e&&i&&e!==i&&await Ji(t,o,i,e,r)}}async function Yi(e,t,n,r,o,i){for(const[e,s]of Object.entries(t)){const t=o[e];if(!t||!Je(t))continue;const a=n[e]??"";await Ji(r,[e],s,a,i)}}const Qi=[{name:"storage-manager-hook",config:({filter:e,action:t},{database:n,env:r,services:o,getSchema:i,logger:s})=>{t("server.start",async()=>{await async function(e,t,n,r){try{if(await e.schema.hasColumn("directus_settings",Z))return;const o=await n(),i=new t.FieldsService({database:e,schema:o,accountability:null}),s=await i.readAll("directus_settings");if(s?.some(e=>e.field===Z))return;await i.createField("directus_settings",{field:Z,type:"json",meta:{collection:"directus_settings",field:Z,interface:"input-code",hidden:!0,note:"Storage Manager extension settings (do not edit manually)"},schema:null}),r.info(`[storage-manager] Created directus_settings.${Z}`)}catch(e){r.warn(`[storage-manager] Could not ensure settings field: ${e?.message}`)}}(n,o,i,s)}),e("settings.update",e=>(Z in e&&Pe(),e)),e("files.create",async e=>{try{const t=String(r.STORAGE_LOCATIONS??"local").split(",").map(e=>e.trim()).filter(Boolean),o=String(e.storage??t[0]??"local"),i=Ze(await Oe(n),o);if(!Je(i))return e;const s=await Xe(i,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("folders.create",async e=>{try{const t=e.keys??(e.key?[e.key]:[]);for(const e of t)await Be(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 Oe(n),o=Object.values(r.locations).some(e=>Je(e)&&qe(e.prefix_strategy)),i=t.keys??(t.key?[t.key]:[]),s=String(e.name);for(const e of i){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}),!o)continue;const r=await Gi(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 Oe(n),r=e.keys??(e.key?[e.key]:[]);for(const e of r){const r=c.get(e);c.delete(e),r&&await Me(e,r.oldName,r.newName,r.parent,n,s);const o=a.get(e);a.delete(e),o&&await Ki(0,o,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 Oe(n),r=Object.values(t.locations).some(e=>Je(e)),o=Object.values(t.locations).some(e=>Je(e)&&qe(e.prefix_strategy));for(const i of e){const e=await We(i,n);if(e&&d.set(i,e),!r)continue;const s=await Vi(i,n,t.locations);if(Object.keys(s.folderPaths).length&&l.set(i,s),o){const e=await Hi(i,n);e&&Object.keys(e.siblingOldPaths).length&&u.set(i,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 Oe(n);for(const r of t){const t=d.get(r);d.delete(r),t&&await Re(r,t.parent,t.name,n,s);const o=l.get(r);l.delete(r),o&&await Yi(0,o.folderPaths,o.parentPaths,n,e.locations,s);const i=u.get(r);u.delete(r),i&&await Xi(i,n,e.locations,s)}}catch(e){s.error(`[storage-manager] Folder delete sync error: ${e?.message}`)}});const p=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),o=[];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&&o.push({id:String(e.id),storage:n,filename_disk:t})}return o}(n,e);for(const e of t)p.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=p.get(e);t&&(p.delete(e),n.push(t))}if(n.length)try{await async function(e,t){if(!e.length)return;const n=await f();for(const r of e)try{const e=n.location(r.storage);await $(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}`)}})}}],es=[{name:"storage-manager-endpoint",config:ft}],ts=[{name:"storage-manager-operation",config:pt}];export{es as endpoints,Qi as hooks,ts 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 o from"node:fs";import{pathToFileURL as i}from"node:url";import s from"node:fs/promises";import{randomUUID as a}from"node:crypto";let c=null;async function l(e){try{const t=await import(e),n=t?.getStorage||t?.default?.getStorage;if("function"==typeof n)return n}catch{}return null}async function u(e){if(!o.existsSync(e))return null;try{const t=r(n.join(process.cwd(),"package.json"))(e),o=t?.getStorage||t?.default?.getStorage;if("function"==typeof o)return o}catch{}try{return await l(i(e).href)}catch{return null}}async function d(){if(c)return c;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 l(t);if(e)return c=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"],o=[];for(const e of t)for(const t of r)o.push(n.join(e,t));return o}()){const t=await u(e);if(t)return c=t,t}throw new Error("Could not resolve Directus getStorage(). Ensure this extension runs inside the Directus API process (not sandboxed).")}async function f(){return(await d())()}async function p(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 g(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 h(e,t){if("function"==typeof e.exists)return await e.exists(t);try{return await m(e,t),!0}catch{return!1}}async function m(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 y(e,t){if("function"!=typeof e.delete)throw new Error("Storage disk does not support delete");await e.delete(t)}async function*_(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 w=/__[a-f0-9]{16,}(?:\.[^.]+)?$/i;function v(e){const t=String(e||"").replace(/\\/g,"/").replace(/^\/+/,""),r=n.posix.parse(t);return{dir:r.dir,stem:r.name}}function k(e,t){return e.startsWith(`${t}__`)&&w.test(e)}async function b(e,t){if("function"!=typeof e.list)return[];const{dir:r,stem:o}=v(t);if(!r)return[];const i=[];for await(const t of e.list(`${r}/${o}`)){const e=String(t||"").replace(/^[/\\]+/,""),s=n.posix.basename(e);n.posix.dirname(e)===r&&k(s,o)&&i.push(e)}return i}async function S(e,t){const n=await async function(e,t){if("function"!=typeof e.list)return[];const{stem:n}=v(t),r=[];for await(const t of e.list(n)){const e=String(t||"").replace(/^[/\\]+/,"");e.includes("/")||k(e,n)&&r.push(e)}return r}(e,t),r=await b(e,t);return[...new Set([...n,...r])]}async function $(e,t){const n=await S(e,t);for(const t of n)try{await y(e,t)}catch{}try{await y(e,t)}catch{}}const z={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 j(e,t){const n=e[t];if(null==n)return null;const r=String(n).trim();return""===r?null:r}function x(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 E(e,t){return j(e,`STORAGE_${t.toUpperCase()}_DRIVER`)||"local"}function A(e,t){return j(e,`STORAGE_${t.toUpperCase()}_ROOT`)}function P(e,t){return j(e,`STORAGE_${t.toUpperCase()}_BUCKET`)||j(e,`STORAGE_${t.toUpperCase()}_CONTAINER_NAME`)}async function O(e,t,r){const i=E(e,r),{file_count:s,total_bytes:a}=await async function(e,t){const n=await e("directus_files").where({storage:t}).select(e.raw("count(*) as file_count"),e.raw("coalesce(sum(filesize), 0) as total_bytes")).first();return{file_count:Number(n?.file_count||0),total_bytes:Number(n?.total_bytes||0)}}(t,r);let c={disk_total_bytes:null,disk_free_bytes:null,disk_used_bytes:null,disk_used_percent:null,disk_available:!1};return"local"===i&&(c=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",i=n.isAbsolute(e)?e:n.join(r,e);try{if(!o.existsSync(i))return t;const e=o.promises.statfs;if("function"==typeof e){const t=await e(i),n=Number(t.bsize||t.frsize||0),r=n*Number(t.blocks||0),o=n*Number(t.bavail??t.bfree??0),s=Math.max(0,r-o);return{disk_total_bytes:r||null,disk_free_bytes:o||null,disk_used_bytes:s||null,disk_used_percent:r>0?s/r*100:null,disk_available:r>0}}}catch{}return t}(A(e,r))),{location:r,driver:i,file_count:s,total_bytes:a,...c}}async function I(e,t,n){const r=await O(e,t,n),o=function(e){const t=String(e||"local").toLowerCase();return z[t]||{id:t,label:t,short:t.slice(0,8).toUpperCase(),icon:"storage"}}(r.driver);return{...r,label:o.label,short:o.short,icon:o.icon,root:A(e,n),bucket:P(e,n),folder_count:0,mirror_directus_folders:!1}}const Z="storage_manager",T=".keep",N={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 F(e){return String(e||"").replace(/\\/g,"/").replace(/^\/+|\/+$/g,"").replace(/\/+/g,"/")}function C(...e){return e.map(e=>F(e)).filter(Boolean).join("/")}function D(e,t,r,o=!1){const i=F(t),s=F(e);if(o)return s?i?`${i}/${s}`:s:i;const a=(r||[]).map(e=>F(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),o=r?`${t}/${r}`:t;return i?`${i}/${o}`:o}const c=n.posix.basename(s);return i?`${i}/${c}`:c}function U(e){return n.basename(e)===T}function B(e,t){const r=process.env.PWD||process.cwd()||"/directus",o=n.isAbsolute(e)?e:n.join(r,e),i=n.resolve(o,t);if(!i.startsWith(n.resolve(o)))throw new Error("Invalid storage path");return i}function M(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===T)throw new Error("Invalid folder name");return t}async function R(e,t,n){const r=new Set,o=E(n,e),i=A(n,e),a=F(t);if("local"===o&&i){const e=B(i,a||".");try{const t=await s.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 f()).location(e),n=a?`${a}/`:"";for await(const e of _(t,n)){const t=String(e||"").replace(/^[/\\]+/,"");if(!t.startsWith(n)&&n)continue;const o=n?t.slice(n.length):t,i=o.split("/")[0];i&&!i.startsWith(".")&&(o.includes("/")?r.add(i):U(t))}}catch{}return r}async function W(e,t,n){const r=new Set,o=F(n),i=await e("directus_files").select("filename_disk").where("storage",t),s=o?`${o}/`:"";for(const e of i){const t=String(e.filename_disk||"").replace(/^[/\\]+/,"");if(!t)continue;if(s&&!t.startsWith(s))continue;const n=s?t.slice(s.length):t,o=n.indexOf("/");if(o<=0)continue;const i=n.slice(0,o);i&&!i.startsWith(".")&&r.add(i)}return r}async function q(e,t,r){const o=new Set;if("local"===E(r,e))return o;const i=F(t),s=i?`${i}/`:"";try{const t=(await f()).location(e);for await(const e of _(t,s)){const t=String(e||"").replace(/^[/\\]+/,"");if(!U(t))continue;const r=F(n.posix.dirname(t));if(i){if(r===i)continue;if(!r.startsWith(`${i}/`))continue;const e=r.slice(i.length+1).split("/")[0];e&&!e.startsWith(".")&&o.add(e)}else{const e=r.split("/").filter(Boolean);1===e.length&&o.add(e[0])}}}catch{}return o}function L(e,t){const n=F(t).split("/").filter(Boolean);for(let t=1;t<=n.length;t++)e.add(n.slice(0,t).join("/"))}async function J(e,t){const r=new Set,o=await e("directus_files").select("filename_disk").where("storage",t);for(const e of o){const t=String(e.filename_disk||"").replace(/^[/\\]+/,"");if(!t||U(t))continue;const o=F(n.posix.dirname(t));o&&"."!==o&&L(r,o)}return r}async function V(e,t){const n=new Set,r=E(t,e),o=A(t,e);if("local"!==r||!o)return n;return await async function e(t){const r=B(o,t||".");let i;try{i=await s.readdir(r,{withFileTypes:!0})}catch{return}for(const r of i){if(!r.isDirectory()||!r.name||r.name.startsWith("."))continue;const o=C(t,r.name);n.add(o),await e(o)}}(""),n}async function G(e,t){const r=new Set;if("local"===E(t,e))return r;try{const t=(await f()).location(e);for await(const e of _(t,"")){const t=String(e||"").replace(/^[/\\]+/,"");if(!U(t))continue;const o=F(n.posix.dirname(t));o&&"."!==o&&L(r,o)}}catch{}return r}async function H(e,t,n){const r=new Set;for(const n of await J(e,t))r.add(n);for(const e of await V(t,n))r.add(e);for(const e of await G(t,n))r.add(e);return function(e){const t=Array.from(new Set(e.map(e=>F(e)).filter(Boolean))).sort((e,t)=>e.localeCompare(t)),n=new Map;for(const e of t){const t=e.includes("/")?e.slice(e.lastIndexOf("/")+1):e;n.set(e,{name:t,path:e})}const r=[];for(const e of t){const t=n.get(e),o=e.includes("/")?e.slice(0,e.lastIndexOf("/")):"";if(o&&n.has(o)){const e=n.get(o);e.children||(e.children=[]),e.children.push(t)}else r.push(t)}const o=e=>{e.sort((e,t)=>e.name.localeCompare(t.name));for(const t of e)t.children?.length&&o(t.children)};return o(r),r}(Array.from(r))}function K(e){let t=0;for(const n of e)t+=1,n.children?.length&&(t+=K(n.children));return t}async function X(e,t,n){try{return K(await H(e,t,n))}catch{return 0}}async function Y(e,t,r){const o=await async function(e,t,n){const r=new Set;for(const n of await J(e,t))r.add(n);for(const e of await V(t,n))r.add(e);for(const e of await G(t,n))r.add(e);return Array.from(r)}(e,t,r),i=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||U(t))continue;const r=F(n.posix.dirname(t));r&&"."!==r&&L(i,r)}return o.filter(e=>!i.has(e))}function Q(e,t,n){const r=F(e);if(!r)return"";if(null==t)return r;if(n?.length)return D(`${r}/__folder__`,t,n).replace(/\/__folder__$/,"");const o=F(t);return o?`${o}/${r}`:r}async function ee(e,t,n){const r=F(t);if(!r)return;let o="";for(const t of r.split("/").filter(Boolean))await re(e,t,o,n),o=C(o,t)}async function te(e,t,n){const r=F(t);if(!r)return;if("local"===E(n,e)){const t=A(n,e);if(!t)return;const o=B(t,r);try{await s.rm(o,{recursive:!0,force:!0})}catch{}return}try{const t=(await f()).location(e),n=`${r}/${T}`;await h(t,n)&&await y(t,n)}catch{}}async function ne(e){let t=await Y(e.database,e.sourceLocation,e.env);t=function(e,t,n){if(t?.length){const n=t.map(e=>F(e)).filter(Boolean);return e.filter(e=>n.some(t=>e===t||e.startsWith(`${t}/`)))}if(n){const t=F(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 n=0;for(const r of t){const t=Q(r,e.targetPath,e.sourceFolders);if(t)try{await ee(e.targetLocation,t,e.env),n+=1}catch(t){e.logger?.warn(`[storage-manager] Failed copying empty folder ${r}: ${t?.message||t}`)}}if(e.removeSource&&n)for(const n of[...t].sort((e,t)=>t.length-e.length))try{await te(e.sourceLocation,n,e.env),await se(e.sourceLocation,`${n}/.keep`,e.env)}catch{}return n}async function re(t,n,r,o){const i=C(r,M(n));if("local"===E(o,t)){const e=A(o,t);if(!e)throw new Error(`Local storage “${t}” has no STORAGE_${t.toUpperCase()}_ROOT`);const n=B(e,i);return await s.mkdir(n,{recursive:!0}),{path:i}}const a=(await f()).location(t),c=`${i}/${T}`;if(!await h(a,c)){const t=e.from([Buffer.alloc(0)]);await g(a,c,t,"application/octet-stream")}return{path:i}}async function oe(e,t,n,r,o,i,s,a=!1){const c=(await f()).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=D(d,r,s,a);if(d&&d!==f)try{if(!await h(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 h(c,f)){const e=await p(c,d);if(await g(c,f,e,n.type),!await h(c,f))throw new Error("Write verification failed")}try{const e=await b(c,d);for(const t of e)try{await y(c,t)}catch{}}catch{}await y(c,d),await e("directus_files").where("id",u).update({filename_disk:f}),await se(t,d,i),l.push({id:u,from:d,to:f,status:"moved"}),o?.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)}),o?.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 ie(e){const t=F(e),n=t.lastIndexOf("/");return-1===n?"":t.slice(0,n)}async function se(e,t,n){if(!n||"local"!==E(n,e))return;const r=A(n,e);if(!r)return;let o=ie(t);for(;o;){const e=B(r,o);try{if((await s.readdir(e)).length>0)return;await s.rmdir(e)}catch{return}o=ie(o)}}async function ae(t,r,o,i,a,c){const l=F(o),u=F(i);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(M(n.posix.basename(u)),await async function(e,t,r,o){const i=F(r);if(!i)return!1;if(await e("directus_files").select("id").where("storage",t).whereRaw("filename_disk LIKE ?",[`${i}/%`]).first())return!0;const s=ie(i),a=n.posix.basename(i),c=new Set;for(const n of await W(e,t,s))c.add(n);for(const e of await R(t,s,o))c.add(e);for(const e of await q(t,s,o))c.add(e);return c.has(a)}(t,r,u,a))throw new Error(`Folder already exists: ${u}`);const{moved:d,failed:m}=await ce(t,r,l,u,c);if(m>0)throw new Error(`Failed to relocate ${m} file(s) under ${l}`);if("local"===E(a,r)){const e=A(a,r);if(!e)throw new Error(`Local storage “${r}” has no STORAGE_${r.toUpperCase()}_ROOT`);const t=B(e,l),o=B(e,u);await s.mkdir(n.dirname(o),{recursive:!0});try{await s.access(t);try{await s.access(o);const e=await s.readdir(t,{withFileTypes:!0});for(const r of e){const e=n.join(t,r.name),i=n.join(o,r.name);try{await s.rename(e,i)}catch{}}await s.rm(t,{recursive:!0,force:!0})}catch{await s.rename(t,o)}}catch{await s.mkdir(o,{recursive:!0})}}else{const t=(await f()).location(r),n=`${l}/`;try{for await(const e of _(t,n)){const r=String(e||"").replace(/^[/\\]+/,"");if(!r.startsWith(n))continue;const o=u+r.slice(l.length);try{if(await h(t,o)){await y(t,r);continue}const e=await p(t,r);await g(t,o,e,"application/octet-stream"),await y(t,r)}catch(e){c?.warn(`[storage-manager] Folder leftover move failed ${r}: ${e?.message}`)}}}catch{}const o=`${u}/${T}`;if(!await h(t,o)){const n=e.from([Buffer.alloc(0)]);await g(t,o,n,"application/octet-stream")}const i=`${l}/${T}`;if(await h(t,i))try{await y(t,i)}catch{}}return c?.info(`[storage-manager] Relocated folder ${l} → ${u} on ${r} (${d} file(s))`),{path:u,moved:d,failed:m}}async function ce(e,t,n,r,o){const i=F(n),s=F(r);if(!i||i===s)return{moved:0,failed:0};const a=await e("directus_files").select("id","filename_disk","type").where("storage",t).whereRaw("filename_disk LIKE ?",[`${i}/%`]);if(!a.length)return{moved:0,failed:0};const c=(await f()).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(`${i}/`))continue;if(U(a))continue;const d=a.slice(i.length).replace(/^\//,""),f=s?`${s}/${d}`:d;try{if(a===f){l++;continue}if(!await h(c,a)){await e("directus_files").where("id",r).update({filename_disk:f}),l++,o?.warn(`[storage-manager] Prefix relocate DB-only (missing source): ${a} → ${f}`);continue}if(await h(c,f))throw new Error(`Target already exists: ${f}`);const i=await p(c,a);if(await g(c,f,i,n.type),!await h(c,f))throw new Error("Write verification failed");try{const e=await b(c,a);for(const t of e)try{await y(c,t)}catch{}}catch{}await y(c,a),await e("directus_files").where("id",r).update({filename_disk:f}),l++,o?.info(`[storage-manager] Prefix relocate ${a} → ${f} on ${t}`)}catch(e){u++,o?.warn(`[storage-manager] Prefix relocate failed for ${r}: ${e?.message}`)}}return{moved:l,failed:u}}function le(e){return String(e.title||e.filename_download||e.filename_disk||e.id)}async function ue(e,t,n,r){await $(e,t.filename_disk);try{await se(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 de(e,t,n,r){const o=new Array(e.length);let i=0;const s=Array.from({length:Math.min(t,e.length)||1},()=>async function(){for(;i<e.length;){if(r?.())return;const t=i++;o[t]=await n(e[t],t)}}());return await Promise.all(s),o}async function fe(e,t,r,o){let i;try{i=await S(e,r)}catch(e){return void o?.warn?.(`[storage-manager] Could not list asset transforms for ${r}: ${e instanceof Error?e.message:String(e)}`)}for(const r of i)try{const o=n.posix.basename(r);if(await h(t,o))continue;const i=await p(e,r);await g(t,o,i,null)}catch(e){o?.warn?.(`[storage-manager] Failed copying asset transform ${r}: ${e instanceof Error?e.message:String(e)}`)}}async function pe(e,n,r,o,i,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 y=await f(),_=y.location(e.storage),w=y.location(n);if(!await h(_,e.filename_disk))return{...u,status:"failed",error:`Source object missing on ${e.storage}`};if(await o("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 h(w,d)){if(await fe(_,w,e.filename_disk,i),await o("directus_files").where({id:e.id}).update({storage:n,filename_disk:d}),"move"===r&&!c)try{await ue(_,e,l,i)}catch(t){i?.warn?.(`[storage-manager] DB updated but failed deleting source ${e.id}: ${t instanceof Error?t.message:String(t)}`)}const t=await m(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 p(_,e.filename_disk),k=s?v.pipe((b=s,new t({transform(e,t,n){const r=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e);r>0&&b(r),n(null,e)}}))):v;var b;try{await g(w,d,k,e.type)}catch(e){try{await h(w,d)&&await $(w,d)}catch{}return{...u,status:"failed",error:`Write failed: ${e instanceof Error?e.message:String(e)}`}}if(!await h(w,d))return{...u,status:"failed",error:"Target write did not persist (exists check failed)"};let S=0;try{S=(await m(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&&S>0){const t=Number(e.filesize);if(Math.abs(t-S)>Math.max(64,.01*t)&&S<.95*t){try{await $(w,d)}catch{}return{...u,status:"failed",error:`Size mismatch after write (expected ~${t}, got ${S})`}}}await fe(_,w,e.filename_disk,i);try{await o("directus_files").where({id:e.id}).update({storage:n,filename_disk:d})}catch(e){try{await $(w,d)}catch{}return{...u,status:"failed",error:`DB update failed: ${e instanceof Error?e.message:String(e)}`}}if("move"===r&&!c)try{await ue(_,e,l,i)}catch(t){return i?.warn?.(`[storage-manager] Moved ${e.id} to ${n} but source delete failed: ${t instanceof Error?t.message:String(t)}`),{...u,status:"moved",bytes:S,error:`Moved, but source cleanup failed: ${t instanceof Error?t.message:String(t)}`}}return{...u,status:"move"===r?"moved":"copied",bytes:S}}async function ge(e){const{fileIds:t,targetStorage:n,mode:r,database:o,logger:i,onProgress:s,isCancelled:a,keepSourceFileOnDisk:c,targetPath:l,sourceFolders:u,preservePaths:d,includeEmptyFolders:f,sourceStorage:p,sourcePath:g,env:h}=e,m=Math.min(8,Math.max(1,Number(e.concurrency)||3)),y=Date.now(),_=Array.from(new Set(t.filter(Boolean)));async function w(e){if(!f||!h||a?.())return;const t=p||e||null;if(t&&t!==n)try{await ne({database:o,sourceLocation:t,targetLocation:n,env:h,targetPath:l,sourceFolders:u,sourcePath:g,removeSource:"move"===r&&!c,logger:i})}catch(e){i?.warn?.(`[storage-manager] Empty folder copy failed: ${e instanceof Error?e.message:String(e)}`)}}if(0===_.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 o("directus_files").select("id","storage","filename_disk","filename_download","title","type","filesize").whereIn("id",_),k=new Map(v.map(e=>[String(e.id),e])),b=v.reduce((e,t)=>e+(Number(t.filesize)||0),0),S=v.length&&v.every(e=>e.storage===v[0].storage)?v[0].storage:null;s?.({type:"start",mode:r,from:S,to:n,total:_.length,total_bytes:b});let $=0,z=0,j=0,x=0,E=0;const A=new Map;let P=0;const O=await de(_,m,async e=>{if(a?.())return{id:e,filename_disk:"",from:"",to:n,status:"failed",error:"Cancelled"};const t=k.get(e),f=++E;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:_.length,result:t,name:e,succeeded:z,skipped:j,failed:x,transferred_bytes:$,total_bytes:b,elapsed_ms:Date.now()-y}),t}let p;s?.({type:"file_start",index:f,total:_.length,id:t.id,name:le(t),filename_disk:t.filename_disk,from:t.storage,to:n,bytes:Number(t.filesize)||0}),A.set(t.id,0);try{p=await pe(t,n,r,o,i,e=>((e,t,n)=>{$+=n;const r=(A.get(t.id)||0)+n;A.set(t.id,r);const o=Date.now();o-P<120||(P=o,s?.({type:"file_bytes",index:e,id:t.id,file_transferred:r,file_bytes:Number(t.filesize)||0,transferred_bytes:$,total_bytes:b,elapsed_ms:o-y}))})(f,t,e),null!=l?function(e,t,n,r=!1){return D(e,t,n,r)}(t.filename_disk,l,u,d):void 0,Boolean(c),h)}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=A.get(t.id)||0,n=Number(p.bytes)||Number(t.filesize)||0;n>e&&($+=n-e,A.set(t.id,n))}else"skipped"===p.status?j+=1:x+=1;return s?.({type:"file_done",index:f,total:_.length,result:p,name:le(t),succeeded:z,skipped:j,failed:x,transferred_bytes:$,total_bytes:b,elapsed_ms:Date.now()-y}),p},a);await w(S);const I={mode:r,target_storage:n,total:O.filter(Boolean).length,succeeded:z,skipped:j,failed:x,results:O.filter(Boolean),transferred_bytes:$,total_bytes:b,elapsed_ms:Date.now()-y};return i?.info?.(`[storage-manager] ${r} → ${n}: ${z} ok, ${j} skipped, ${x} failed (of ${I.total})`),s?.({type:"done",data:I}),I}const he=new Set(["image/jpeg","image/jpg","image/png","image/webp","image/gif","image/tiff","image/tif","image/avif"]);let me;function ye(e){if(!e)return!1;const t=e.toLowerCase();return"image/svg+xml"!==t&&(he.has(t)||t.startsWith("image/"))}async function _e(e){const t=await async function(){if(void 0!==me)return me;try{const e=r(n.join(process.cwd(),"package.json"))("sharp"),t="function"==typeof e?e:e?.default;if("function"==typeof t)return me=t,me}catch{}try{const e=await import("sharp"),t="function"==typeof e.default?e.default:e;if("function"==typeof t)return me=t,me}catch{}return me=null,null}();if(!t)return null;try{const n=await t(e,{failOn:"none"}).metadata();let r=n.width??0,o=n.height??0;if(n.orientation&&n.orientation>=5){const e=r;r=o,o=e}if(r>0&&o>0)return{width:r,height:o}}catch{}return null}async function we(e,t){let n,r;try{n=await p(e,t)}catch{return null}try{r=await async function(e,t){const n=[];let r=0;try{for await(const o of e){const e=Buffer.isBuffer(o)?o:Buffer.from(o);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 o=Buffer.concat(n);return o.length>t?o.subarray(0,t):o}(n,2097152)}catch{return null}return r.length?await _e(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 ve=/__[a-f0-9]{16,}(?:\.[^.]+)?$/i;function ke(e){return ve.test(n.basename(e))}function be(e){const t=n.basename(e);return!(t&&!t.startsWith("."))||("directus-health-file"===t||!!ke(e))}const Se={".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 $e(e){const t=n.extname(e).toLowerCase();return Se[t]||null}function ze(e){const t=n.parse(n.basename(e)).name;return t.replace(/_/g," ").replace(/\s+/g," ").trim()||t||e}function je(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 xe(e,t){const r=new Set;if(t){const o=E(t,e),i=A(t,e);if("local"===o&&i){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,o=""){let i;try{i=await s.readdir(t,{withFileTypes:!0})}catch{return}for(const s of i){const i=o?`${o}/${s.name}`:s.name;s.isDirectory()?await e(n.join(t,s.name),i):s.isFile()&&(be(i)||r.push(i))}}(t),r}(i))r.add(e);return Array.from(r)}}const o=(await f()).location(e);try{for await(const e of _(o,"")){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,o){const i=String(o||"").replace(/\\/g,"/").replace(/^\/+|\/+$/g,"").replace(/\/+/g,"/"),s=await xe(t,r),a=i?s.filter(e=>e===i||e.startsWith(`${i}/`)):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 f()).location(t),d=[];for(const e of a){if(l.has(e))continue;let t=0;try{const n=await m(u,e);t=Number(n.size)||0}catch{t=0}d.push({filename_disk:e,filesize:t,type:$e(e),suggested_id:je(e),filename_download:n.basename(e),title:ze(e)})}return d.sort((e,t)=>e.filename_disk.localeCompare(t.filename_disk)),{orphans:d,scanned:a.length,known:l.size,path:i}}let Ae=null;function Pe(){Ae=null}async function Oe(e){if(Ae)return Ae;try{if(!await e.schema.hasColumn("directus_settings",Z))return Ae={locations:{}},Ae;const t=await e("directus_settings").select(Z).first(),n=t?.[Z],r="string"==typeof n?JSON.parse(n):n??{},o={locations:r.locations??{}};return r&&"object"==typeof r&&"name_mirror_claims"in r&&(o.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)),Ae=o,Ae}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 Ae={locations:{}},Ae;throw e}}async function Ie(e,t){await e("directus_settings").update({[Z]:JSON.stringify(t)}),Ae=t}function Ze(e,t){return{...N,...e.locations[t]??{}}}async function Te(e,t,n,r){try{const o=await e.schema.hasColumn("directus_settings",Z);if(o)return;const i=await n(),s=new t.FieldsService({database:e,schema:i,accountability:{admin:!0}}),a=await s.readAll("directus_settings"),c=a?.some(e=>e.field===Z);if(c&&o)return;await s.createField("directus_settings",{field:Z,type:"json",meta:{collection:"directus_settings",field:Z,special:["cast-json"],interface:"input-code",hidden:!0,note:"Storage Manager extension settings (do not edit manually)"},schema:null}),Pe(),r.info(`[storage-manager] Created directus_settings.${Z}`)}catch(e){r.warn(`[storage-manager] Could not ensure settings field: ${e?.message}`)}}function Ne(e,t){return`${e??""}::${t}`}function Fe(e){const t=new Map;for(const n of e){const e=Ne(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 Ce(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 De(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 Ue(e,t){const n=await Oe(e);if(void 0!==n.name_mirror_claims)return n.name_mirror_claims;const r=function(e){const t={},n=Fe(e);for(const[e,r]of n)r[0]&&(t[e]=r[0]);return t}(await Ce(e)),o={...n,name_mirror_claims:r};return await Ie(e,o),t?.info(`[storage-manager] Initialized name_mirror_claims (${Object.keys(r).length} sibling groups)`),r}async function Be(e,t){const n=await Oe(e);await Ie(e,{...n,name_mirror_claims:t})}async function Me(e,t,n){const r=await t("directus_folders").select("id","name","parent").where("id",e).first();if(!r)return;const o=String(r.name),i=r.parent?String(r.parent):null,s=Ne(i,o),a={...await Ue(t,n)};0!==(await De(t,i,o)).filter(t=>t!==e).length?a[s]:a[s]!==e&&(a[s]=e,await Be(t,a))}async function Re(e,t,n,r,o,i){if(t===n)return;const s={...await Ue(o,i)},a=Ne(r,t),c=Ne(r,n);let l=!1;s[a]===e&&(delete s[a],l=!0);0===(await De(o,r,n)).filter(t=>t!==e).length?s[c]!==e&&(s[c]=e,l=!0):s[c]===e||s[c],l&&await Be(o,s)}async function We(e,t,n,r,o){const i={...await Ue(r,o)},s=Ne(t,n);i[s]===e&&(delete i[s],await Be(r,i))}async function qe(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 Le(e){return"folder"===e}function Je(e){return"folder_id"===e}function Ve(e){return Le(t=e.prefix_strategy)||Je(t);var t}function Ge(e,t,n,r){return(n.length?n:[t]).length<=1||r===t?e:`${e}_${t}`}async function He(e,t){if(!t)return null;return Xe(await Ce(e),t,"name",await Ue(e))}async function Ke(e,t){if(!t)return null;return Xe(await Ce(e),t,"id")}function Xe(e,t,n,r={}){if(!t)return null;const o=new Map;for(const t of e)o.set(t.id,t);const i="name"===n?Fe(e):null,s=[];let a=String(t),c=0;for(;a&&c<50;){const e=o.get(a);if(!e)break;if("id"===n)s.unshift(a);else{const t=Ne(e.parent,e.name),n=i.get(t)??[e.id];s.unshift(Ge(e.name,e.id,n,r[t]??null))}a=e.parent,c++}return s.length?s.join("/"):null}async function Ye(e,t,n){switch(e.prefix_strategy){case"none":default:return null;case"folder":return await He(n,t.folder)||null;case"folder_id":return await Ke(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 Qe(e){return String(e||"").replace(/\\/g,"/").replace(/\//g,"_").trim()}function et(e,t){if(!e)return"";const n=[];let r=e,o=0;for(;r&&o<100;){const e=t.get(r);if(!e)break;n.unshift(Qe(e.name)),r=e.parent,o+=1}return n.filter(Boolean).join("/")}async function tt(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 o=[],i=[t];for(;i.length;){const e=i.pop();o.push(e);for(const t of r.get(e)||[])i.push(t)}return o}async function nt(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}])),o=await tt(e.database,e.folderId);let i=e.database("directus_files").select("id","storage","filename_disk","filesize","type","folder").whereNotNull("filename_disk");e.recursive?null!==e.folderId&&(i=i.whereIn("folder",[e.folderId,...o])):i=null===e.folderId?i.whereNull("folder"):i.whereIn("folder",o);const s=await i,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 o=s[t];if(e.isCancelled?.())break;const i="merge"===e.mode?String(e.targetStorage||""):String(o.storage),g=et(o.folder?String(o.folder):null,r),h=n.posix.basename(String(o.filename_disk||"")),m=g?`${g}/${h}`:h,y=String(o.filename_disk||o.id);if(e.onProgress?.({type:"file_start",index:t+1,total:s.length,id:String(o.id),name:y,filename_disk:String(o.filename_disk||""),from:String(o.storage),to:i,bytes:Number(o.filesize)||0}),e.structureOnly){const n={id:o.id,status:"skipped",filename_disk:m,from:String(o.storage),to:i,error:"Structure-only mode"};a.push(n),u+=1,e.onProgress?.({type:"file_done",index:t+1,total:s.length,result:n,name:y,succeeded:c,skipped:u,failed:l,transferred_bytes:p,total_bytes:d,elapsed_ms:Date.now()-f});continue}try{const n=await pe(o,i,"move",e.database,e.logger,void 0,m,Boolean(e.keepSourceFileOnDisk));a.push(n),"failed"===n.status?l+=1:"skipped"===n.status?u+=1:(c+=1,p+=Number(n.bytes)||Number(o.filesize)||0),e.onProgress?.({type:"file_done",index:t+1,total:s.length,result:n,name:y,succeeded:c,skipped:u,failed:l,transferred_bytes:p,total_bytes:d,elapsed_ms:Date.now()-f})}catch(n){const r={id:o.id,status:"failed",filename_disk:m,from:String(o.storage),to:i,error:n?.message||"Materialize failed"};a.push(r),l+=1,e.onProgress?.({type:"file_done",index:t+1,total:s.length,result:r,name:y,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 rt="directus-extension-storage-manager",ot=`https://www.npmjs.com/package/${rt}`;let it=null;const st=18e5;function at(e){return String(e||"").trim().replace(/^v/,"")}function ct(e){const t=at(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("."):[]}}async function lt(e=!1){if(!e&&it&&Date.now()<it.expiresAt)return it.data;const t=at("1.1.1"),n={npm:ot,github:"https://github.com/domdus/directus-extension-storage-manager",marketplace:null},r={current_version:t,latest_version:null,has_update:!1,registry:"npm",checked_at:(new Date).toISOString(),release_url:n.npm,links:n};try{const e=await fetch(`https://registry.npmjs.org/${encodeURIComponent(rt)}`,{method:"GET",headers:{Accept:"application/json"}});if(!e.ok)throw new Error(`npm registry request failed (${e.status})`);const n=await e.json(),o=at(n?.["dist-tags"]?.latest||"");if(!o)throw new Error("No latest version found in npm dist-tags");const i=function(e,t){const n=ct(e),r=ct(t),o=Math.max(n.nums.length,r.nums.length,3);for(let e=0;e<o;e++){const t=n.nums[e]??0,o=r.nums[e]??0;if(t>o)return 1;if(t<o)return-1}if(!n.prerelease.length&&r.prerelease.length)return 1;if(n.prerelease.length&&!r.prerelease.length)return-1;const i=Math.max(n.prerelease.length,r.prerelease.length);for(let e=0;e<i;e++){const t=n.prerelease[e],o=r.prerelease[e];if(null==t)return-1;if(null==o)return 1;const i=/^[0-9]+$/.test(t)?parseInt(t,10):null,s=/^[0-9]+$/.test(o)?parseInt(o,10):null;if(null==i||null==s){if(null!=i&&null==s)return-1;if(null==i&&null!=s)return 1;if(t>o)return 1;if(t<o)return-1}else{if(i>s)return 1;if(i<s)return-1}}return 0}(o,t)>0,s={...r,latest_version:o,has_update:i,release_url:i?`${ot}?activeTab=versions`:ot,checked_at:(new Date).toISOString()};return it={data:s,expiresAt:Date.now()+st},s}catch(e){const t={...r,error:e?.message||"Update check failed",checked_at:(new Date).toISOString()};return it={data:t,expiresAt:Date.now()+Math.min(3e5,st)},t}}function ut(e,t){return!(!(n=e.accountability)||"object"!=typeof n||!0!==n.admin)||(t.status(403).json({errors:[{message:"Admin access required",extensions:{code:"FORBIDDEN"}}]}),!1);var n}async function dt(e,t,n){if(!t)return[];if(!n)return[t];const r=await e("directus_folders").select("id","parent"),o=new Map;for(const e of r){const t=null==e.parent?null:String(e.parent),n=String(e.id);o.has(t)||o.set(t,[]),o.get(t).push(n)}const i=[],s=[String(t)];for(;s.length;){const e=s.pop();i.push(e);const t=o.get(e)||[];for(const e of t)s.push(e)}return i}async function ft(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");t.source_storage&&n.where("storage",String(t.source_storage));const r=null!=t.source_path?F(String(t.source_path)):"";if(r){if(!t.source_storage)return[];const e=`${r}/`;!1===t.recursive?n.where("filename_disk","like",`${e}%`).whereNot("filename_disk","like",`${e}%/%`):n.where("filename_disk","like",`${e}%`)}if(void 0!==t.folder_id)if(null===t.folder_id||""===t.folder_id)n.whereNull("folder");else{const r=await dt(e,String(t.folder_id),Boolean(t.recursive));0===r.length?n.where("folder",String(t.folder_id)):n.whereIn("folder",r)}return(await n).map(e=>String(e.id))}var pt={id:"storage-manager",handler:(e,t)=>{const{database:r,env:o,logger:i,services:c,getSchema:l}=t;e.use(async(e,t,n)=>{try{await Te(r,c,l,i),n()}catch(e){n(e)}}),e.get("/storages",async(e,t,n)=>{try{if(!ut(e,t))return;const n=x(o),i=await Oe(r),s=await Promise.all(n.map(async e=>{const t=await I(o,r,e);return t.folder_count=await X(r,e,o),t.mirror_directus_folders=Ve(Ze(i,e)),t}));t.json({data:s})}catch(e){n(e)}}),e.get("/update-check",async(e,t,n)=>{try{if(!ut(e,t))return;const n="1"===String(e.query.force||""),r=await lt(n);t.json({data:r})}catch(e){n(e)}}),e.get("/storages/:location",async(e,t,n)=>{try{if(!ut(e,t))return;const n=String(e.params.location);if(!x(o).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const i=await I(o,r,n);i.folder_count=await X(r,n,o);const s=await Oe(r);i.mirror_directus_folders=Ve(Ze(s,n)),t.json({data:i})}catch(e){n(e)}}),e.get("/storages/:location/browse",async(e,t,n)=>{try{if(!ut(e,t))return;const n=String(e.params.location);if(!x(o).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const i=F(String(e.query.path||"")),s=await async function(e,t,n,r){const o=F(n),i=new Set;for(const n of await W(e,t,o))i.add(n);for(const e of await R(t,o,r))i.add(e);for(const e of await q(t,o,r))i.add(e);const s=Array.from(i).sort((e,t)=>e.localeCompare(t)).map(e=>({name:e,path:C(o,e)}));return{path:o,folders:s}}(r,n,i,o);t.json({data:s})}catch(e){n(e)}}),e.get("/storages/:location/folder-tree",async(e,t,n)=>{try{if(!ut(e,t))return;const n=String(e.params.location);if(!x(o).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const i=await H(r,n,o);t.json({data:i})}catch(e){n(e)}}),e.post("/storages/:location/folders",async(e,t,n)=>{try{if(!ut(e,t))return;const n=String(e.params.location);if(!x(o).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const r=e.body||{},i=await re(n,String(r.name||""),String(r.parent_path||""),o);t.json({data:i})}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,a)=>{try{if(!ut(e,n))return;const a=String(e.params.location);if(!x(o).includes(a))return void n.status(404).json({errors:[{message:`Unknown storage location: ${a}`}]});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 p=await async function(e,t,n,r,o,i){const a="delete"===i?.mode?"delete":"move",c=[],l=[];let u=0,d=0;const p=E(r,t),g=(await f()).location(t);for(const f of n){const n=F(f);if(!n){l.push({path:String(f),error:"Invalid path"});continue}const m=ie(n);try{let f=0;if("delete"===a){const r=(await e("directus_files").select("id","filename_disk").where("storage",t).whereRaw("filename_disk LIKE ?",[`${n}/%`])).filter(e=>!U(String(e.filename_disk||""))),o=r.map(e=>String(e.id));if(o.length){if(i?.filesService)await i.filesService.deleteMany(o);else for(const t of r){const n=String(t.id),r=String(t.filename_disk||"");try{r&&await $(g,r)}catch{}await e("directus_files").where("id",n).delete()}f=o.length,d+=o.length}}else{const{moved:r,failed:i}=await ce(e,t,n,m,o);if(u+=r,i>0){l.push({path:n,error:`Could not move ${i} registered file(s) to parent`});continue}}if("local"===p){const e=A(r,t);if(!e)throw new Error("Missing local root");const o=B(e,n);await s.rm(o,{recursive:!0,force:!0})}else try{for await(const e of _(g,`${n}/`)){const t=String(e||"").replace(/^[/\\]+/,"");if(t.startsWith(`${n}/`)&&U(t))try{await y(g,t)}catch{}}}catch{const e=`${n}/${T}`;await h(g,e)&&await y(g,e)}c.push(n),o?.info("delete"===a?`[storage-manager] Deleted storage folder “${n}” on ${t} (deleted ${f} 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,a,l,o,i,{mode:u,filesService:d});n.json({data:p})}catch(e){a(e)}}),e.patch("/storages/:location/folders",async(e,t,s)=>{try{if(!ut(e,t))return;const s=String(e.params.location);if(!x(o).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=C(String(a.parent_path??""),e);d=await ae(r,s,c,t,o,i)}else d=l?await async function(e,t,n,r,o,i){const s=F(n);if(!s)throw new Error("Folder path is required");const a=M(r);return ae(e,t,s,C(ie(s),a),o,i)}(r,s,c,String(a.name||""),o,i):await async function(e,t,r,o,i,s){const a=F(r);if(!a)throw new Error("Folder path is required");return ae(e,t,a,C(F(o),n.posix.basename(a)),i,s)}(r,s,c,String(a.parent_path??""),o,i);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(!ut(e,t))return;const n=String(e.params.location);if(!x(o).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 oe(r,n,a,String(s.target_path??""),i,o,c,Boolean(s.preserve_paths)):{moved:0,failed:0,skipped:0,results:[]};!1!==s.include_empty_folders&&(c.length||s.source_storage)&&await ne({database:r,sourceLocation:String(s.source_storage||n),targetLocation:n,env:o,targetPath:String(s.target_path??""),sourceFolders:c.length?c:void 0,removeSource:!0,logger:i}),t.json({data:l})}catch(e){n(e)}}),e.post("/storages/:location/place-file",async(e,t,i)=>{try{if(!ut(e,t))return;const i=String(e.params.location);if(!x(o).includes(i))return void t.status(404).json({errors:[{message:`Unknown storage location: ${i}`}]});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,o){const i=F(o);if(!i)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===`${i}/${c}`)return a;const l=(await oe(e,r,[t],i)).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),i,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(!ut(e,t))return;const n=String(e.params.location);if(!x(o).includes(n))return void t.status(404).json({errors:[{message:`Unknown storage location: ${n}`}]});const i="string"==typeof e.query.path?e.query.path:"",s=await Ee(r,n,o,i);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(!ut(e,t))return;const s=String(e.params.location);if(!x(o).includes(s))return void t.status(404).json({errors:[{message:`Unknown storage location: ${s}`}]});const c=e.body||{};let l=Array.isArray(c.filename_disks)?c.filename_disks.map(String):[];if(0===l.length){l=(await Ee(r,s,o,c.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,o){const i=(await f()).location(t),s=[];for(const c of r){const r=String(c||"").trim();if(r&&!be(r))try{const c=await e("directus_files").select("id").where({storage:t,filename_disk:r}).first();if(c){s.push({filename_disk:r,id:String(c.id),status:"skipped",error:"Already in database"});continue}if(!await h(i,r)){s.push({filename_disk:r,status:"failed",error:"File not found on disk"});continue}const l=await m(i,r),u=je(r);let d=u||a();u&&await e("directus_files").select("id").where({id:u}).first()&&(d=a());const f=new Date,p=n.basename(r),g=$e(r),y=ze(r);let _=null,w=null;if(ye(g)){const e=await we(i,r);e&&(_=e.width,w=e.height)}await e("directus_files").insert({id:d,storage:t,filename_disk:r,filename_download:p,title:y,type:g,filesize:Number(l.size)||0,width:_,height:w,folder:o?.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===c.folder?null:c.folder});i.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(!ut(e,t))return;const n=String(e.params.location);if(!x(o).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 f()).location(t),o=[];for(const i of n){const n=String(i||"").trim();if(n&&!be(n))try{if(await e("directus_files").select("id").where({storage:t,filename_disk:n}).first()){o.push({filename_disk:n,status:"skipped",error:"Registered in Directus — use File Library to delete"});continue}if(!await h(r,n)){o.push({filename_disk:n,status:"skipped",error:"Not found on disk"});continue}await y(r,n),o.push({filename_disk:n,status:"deleted"})}catch(e){o.push({filename_disk:n,status:"failed",error:e?.message||String(e)})}else o.push({filename_disk:n,status:"skipped",error:n&&ke(n)?"Generated thumbnail":"Ignored path"})}return o}(r,n,a);i.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(!ut(e,t))return;const n=e.query.storage?String(e.query.storage):null,o=void 0!==e.query.folder?"null"===e.query.folder||""===e.query.folder?null:String(e.query.folder):void 0,i=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!==o)if(null===o)d.whereNull("folder");else if(a){const e=await dt(r,o,!0);d.whereIn("folder",e)}else d.where("folder",o);if(i){const e=`%${i.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,h=u.startsWith("-")?"desc":"asc",m=new Set(["uploaded_on","modified_on","filename_download","filesize","title","storage","type"]).has(g)?g:"uploaded_on",y=await d.clone().orderBy(m,h).limit(l).offset((c-1)*l),_=await f,w=await p,v=Number(_?.count||0),k=Number(w?.total_bytes||0);t.json({data:y,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(!ut(e,t))return;const n=void 0===e.query.parent?void 0:"null"===e.query.parent||""===e.query.parent?null:String(e.query.parent),o=e.query.storage?String(e.query.storage):null;let i=r("directus_folders").select("id","name","parent").orderBy("name","asc");null===n?i=i.whereNull("parent"):void 0!==n&&(i=i.where("parent",n));const s=await i,a=[];for(const e of s){const t=String(e.id);let n=r("directus_files").where("folder",t);o&&(n=n.andWhere("storage",o));const i=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(i?.file_count||0),total_bytes:Number(i?.total_bytes||0),child_count:Number(s?.count||0)})}let c=null;if(null==n){let e=r("directus_files").whereNull("folder");o&&(e=e.andWhere("storage",o));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(!ut(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(!ut(e,t))return;const n=String(e.params.id),o=[];let i=n;for(let e=0;e<50&&i;e++){const e=await r("directus_folders").select("id","name","parent").where({id:i}).first();if(!e)break;o.unshift({id:String(e.id),name:e.name}),i=null==e.parent?null:String(e.parent)}t.json({data:o})}catch(e){n(e)}}),e.post("/migrate/dry-run",async(e,t,n)=>{try{if(!ut(e,t))return;const n=e.body||{},i=String(n.target_storage||"").trim(),s=x(o);if(!i||!s.includes(i))return void t.status(400).json({errors:[{message:"Provide a valid target_storage"}]});const a=null!=n.target_path?String(n.target_path):"",c=Boolean(n.preserve_paths),l=Array.isArray(n.source_folders)?n.source_folders.map(String):[],u=await ft(r,n),d=u.length?await r("directus_files").select("id","storage","filesize","filename_disk").whereIn("id",u):[],f=new Set,p=[],g=d.map(e=>{const t=String(e.filename_disk||""),n=D(t,a,l,c),r=F(n.includes("/")?n.slice(0,n.lastIndexOf("/")):"");return r&&f.add(r),{id:String(e.id),storage:String(e.storage),from:t,to:n}}),h=[...new Set(g.map(e=>e.to).filter(Boolean))],m=h.length?await r("directus_files").select("id","filename_disk").where({storage:i}).whereIn("filename_disk",h):[],y=new Map;for(const e of m)y.set(String(e.filename_disk),String(e.id));let _=0;for(const e of g){const t=y.get(e.to),n=Boolean(t&&t!==e.id);n&&(_+=1),p.length<20&&p.push({from:`${e.storage}:${e.from}`,to:`${i}:${e.to}`,skipped:n})}let w=0;const v=n.source_storage?String(n.source_storage):"";if(v&&s.includes(v)){const e=null!=n.source_path?F(String(n.source_path)):"",t=(await Y(r,v,o)).filter(t=>l.length?l.some(e=>{const n=F(e);return t===n||t.startsWith(`${n}/`)}):!e||(t===e||t.startsWith(`${e}/`)));w=t.length;for(const e of t){const t=Q(e,a,l.length?l:void 0);t&&f.add(t)}}t.json({data:{total_files:d.length,total_folders:f.size,empty_folders:w,total_bytes:d.reduce((e,t)=>e+(Number(t.filesize)||0),0),skipped:_,samples:p}})}catch(e){n(e)}}),e.post("/migrate",async(e,t,n)=>{try{if(!ut(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=x(o);if(!c.includes(s))return void t.status(400).json({errors:[{message:`Unknown target storage: ${s}. Available: ${c.join(", ")}`}]});if(E(o,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 ft(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.`}]});i.info(`[storage-manager] Starting ${a} of ${l.length} file(s) → ${s} (by ${e.accountability?.user||"unknown"})`);const d=await ge({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:i,env:o});t.json({data:d})}catch(e){n(e)}}),e.post("/migrate/stream",async(e,t,n)=>{try{if(!ut(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=x(o);if(!c.includes(s))return void t.status(400).json({errors:[{message:`Unknown target storage: ${s}. Available: ${c.join(", ")}`}]});if(E(o,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 ft(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)};i.info(`[storage-manager] Streaming ${a} of ${l.length} file(s) → ${s} (by ${e.accountability?.user||"unknown"})`);try{await ge({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:i,env:o,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,i)=>{try{if(!ut(e,t))return;const i=e.body||{},s="merge"===i.mode?"merge":"preserve",a=void 0===i.folder_id||null===i.folder_id||""===i.folder_id?null:String(i.folder_id),c=String(i.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(!x(o).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}])),o=await tt(e.database,e.folderId);let i=e.database("directus_files").select("id","storage","filename_disk","filesize","folder").whereNotNull("filename_disk");e.recursive?null!==e.folderId&&(i=i.whereIn("folder",[e.folderId,...o])):i=null===e.folderId?i.whereNull("folder"):i.whereIn("folder",o);const s=await i,a=await f(),c=new Set;let l=0;const u=new Map,d=[];for(const t of s){const o="merge"===e.mode?String(e.targetStorage||""):String(t.storage),i=et(t.folder?String(t.folder):null,r),s=n.posix.basename(String(t.filename_disk||"")),f=i?`${i}/${s}`:s,p=`${o}::${f}`;c.has(p)&&(l+=1),c.add(p);const g=String(t.filename_disk||"").replace(/\\/g,"/").replace(/^\/+/,"");if(t.storage!==o||g!==f)try{const e=a.location(o);await h(e,f)&&(l+=1)}catch{}d.length<25&&d.push({id:String(t.id),from:`${t.storage}:${t.filename_disk}`,to_storage:o,to_path:f});const m=u.get(o)||{files:0,bytes:0};m.files+=1,m.bytes+=Number(t.filesize)||0,u.set(o,m)}const p=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:p.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(i.structure_only),recursive:Boolean(i.recursive)});t.json({data:l})}catch(e){i(e)}}),e.post("/materialize",async(e,t,n)=>{try{if(!ut(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(!x(o).includes(c))return void t.status(400).json({errors:[{message:`Unknown target storage: ${c}`}]})}const l=await nt({database:r,logger:i,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(!ut(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(!x(o).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 nt({database:r,logger:i,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(!ut(e,t))return;const n=await Oe(r);t.json({data:{locations:n.locations??{}}})}catch(e){n(e)}}),e.patch("/settings",async(e,t,n)=>{try{if(!ut(e,t))return;const n=e.body;if(!n||"object"!=typeof n.locations)return void t.status(400).json({errors:[{message:'Body must contain a "locations" object.'}]});const o=await r("directus_settings").select(Z).first(),i=o?.[Z],s="string"==typeof i?JSON.parse(i):i??{locations:{}},a={...s.locations??{}};for(const[e,t]of Object.entries(n.locations))a[e]={...N,...s.locations?.[e]??{},...t};const c={locations:a,...void 0!==s.name_mirror_claims?{name_mirror_claims:s.name_mirror_claims}:{}};await r("directus_settings").update({[Z]:JSON.stringify(c)}),Pe(),t.json({data:{locations:c.locations}})}catch(e){n(e)}}),e.delete("/settings/locations/:location",async(e,t,n)=>{try{if(!ut(e,t))return;const n=String(e.params.location),o=await r("directus_settings").select(Z).first(),i=o?.[Z],s="string"==typeof i?JSON.parse(i):i??{locations:{}};delete s.locations[n],await r("directus_settings").update({[Z]:JSON.stringify(s)}),Pe(),t.json({data:s})}catch(e){n(e)}})}};var gt={id:"storage-manager-operation",handler:async(e,{env:t,database:n,logger:r})=>{const o="copy"===e.mode?"copy":"move",i=String(e.target_storage||"").trim();if(!i)throw new Error("target_storage is required");const s=x(t);if(!s.includes(i))throw new Error(`Unknown target storage "${i}". 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"),o=new Map;for(const e of r){const t=null==e.parent?null:String(e.parent),n=String(e.id);o.has(t)||o.set(t,[]),o.get(t).push(n)}const i=[],s=[String(t)];for(;s.length;){const e=s.pop();i.push(e);for(const t of o.get(e)||[])s.push(t)}return i}(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] ${o} ${a.length} file(s) → ${i}`),await ge({fileIds:a,targetStorage:i,mode:o,concurrency:c,database:n,logger:r})}};const ht=["interface","display","layout","module","panel","theme"],mt=["hook","endpoint"],yt=["operation"];function _t(e,t,n){function r(n,r){var o;Object.defineProperty(n,"_zod",{value:n._zod??{},enumerable:!1}),(o=n._zod).traits??(o.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 o=n?.Parent??Object;class i extends o{}function s(e){var t;const o=n?.Parent?new i:this;r(o,e),(t=o._zod).deferred??(t.deferred=[]);for(const e of o._zod.deferred)e();return o}return Object.defineProperty(i,"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 wt extends Error{constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}}class vt extends Error{constructor(e){super(`Encountered unidirectional transform during encode: ${e}`),this.name="ZodEncodeError"}}const kt={};function bt(e){return kt}function St(e,t){return"bigint"==typeof t?t.toString():t}function $t(e){return{get value(){{const t=e();return Object.defineProperty(this,"value",{value:t}),t}}}}function zt(e){return null==e}function jt(e){const t=e.startsWith("^")?1:0,n=e.endsWith("$")?e.length-1:e.length;return e.slice(t,n)}const xt=Symbol("evaluating");function Et(e,t,n){let r;Object.defineProperty(e,t,{get(){if(r!==xt)return void 0===r&&(r=xt,r=n()),r},set(n){Object.defineProperty(e,t,{value:n})},configurable:!0})}function At(e,t,n){Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0})}function Pt(...e){const t={};for(const n of e){const e=Object.getOwnPropertyDescriptors(n);Object.assign(t,e)}return Object.defineProperties({},t)}function Ot(e){return JSON.stringify(e)}const It="captureStackTrace"in Error?Error.captureStackTrace:(...e)=>{};function Zt(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}const Tt=$t(()=>{if("undefined"!=typeof navigator&&navigator?.userAgent?.includes("Cloudflare"))return!1;try{return new Function(""),!0}catch(e){return!1}});function Nt(e){if(!1===Zt(e))return!1;const t=e.constructor;if(void 0===t)return!0;const n=t.prototype;return!1!==Zt(n)&&!1!==Object.prototype.hasOwnProperty.call(n,"isPrototypeOf")}function Ft(e){return Nt(e)?{...e}:Array.isArray(e)?[...e]:e}const Ct=new Set(["string","number","symbol"]);function Dt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ut(e,t,n){const r=new e._zod.constr(t??e._zod.def);return t&&!n?.parent||(r._zod.parent=e),r}function Bt(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 Mt(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 Rt(e,t){return t.map(t=>{var n;return(n=t).path??(n.path=[]),t.path.unshift(e),t})}function Wt(e){return"string"==typeof e?e:e?.message}function qt(e,t,n){const r={...e,path:e.path??[]};if(!e.message){const o=Wt(e.inst?._zod.def?.error?.(e))??Wt(t?.error?.(e))??Wt(n.customError?.(e))??Wt(n.localeError?.(e))??"Invalid input";r.message=o}return delete r.inst,delete r.continue,t?.reportInput||delete r.input,r}function Lt(e){return Array.isArray(e)?"array":"string"==typeof e?"string":"unknown"}function Jt(...e){const[t,n,r]=e;return"string"==typeof t?{message:t,code:"custom",input:n,inst:r}:{...t}}const Vt=(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,St,2),Object.defineProperty(e,"toString",{value:()=>e.message,enumerable:!1})},Gt=_t("$ZodError",Vt),Ht=_t("$ZodError",Vt,{Parent:Error});const Kt=e=>(t,n,r,o)=>{const i=r?Object.assign(r,{async:!1}):{async:!1},s=t._zod.run({value:n,issues:[]},i);if(s instanceof Promise)throw new wt;if(s.issues.length){const t=new(o?.Err??e)(s.issues.map(e=>qt(e,i,bt())));throw It(t,o?.callee),t}return s.value},Xt=e=>async(t,n,r,o)=>{const i=r?Object.assign(r,{async:!0}):{async:!0};let s=t._zod.run({value:n,issues:[]},i);if(s instanceof Promise&&(s=await s),s.issues.length){const t=new(o?.Err??e)(s.issues.map(e=>qt(e,i,bt())));throw It(t,o?.callee),t}return s.value},Yt=e=>(t,n,r)=>{const o=r?{...r,async:!1}:{async:!1},i=t._zod.run({value:n,issues:[]},o);if(i instanceof Promise)throw new wt;return i.issues.length?{success:!1,error:new(e??Gt)(i.issues.map(e=>qt(e,o,bt())))}:{success:!0,data:i.value}},Qt=Yt(Ht),en=e=>async(t,n,r)=>{const o=r?Object.assign(r,{async:!0}):{async:!0};let i=t._zod.run({value:n,issues:[]},o);return i instanceof Promise&&(i=await i),i.issues.length?{success:!1,error:new e(i.issues.map(e=>qt(e,o,bt())))}:{success:!0,data:i.value}},tn=en(Ht),nn=e=>(t,n,r)=>{const o=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Kt(e)(t,n,o)},rn=e=>(t,n,r)=>Kt(e)(t,n,r),on=e=>async(t,n,r)=>{const o=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Xt(e)(t,n,o)},sn=e=>async(t,n,r)=>Xt(e)(t,n,r),an=e=>(t,n,r)=>{const o=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Yt(e)(t,n,o)},cn=e=>(t,n,r)=>Yt(e)(t,n,r),ln=e=>async(t,n,r)=>{const o=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return en(e)(t,n,o)},un=e=>async(t,n,r)=>en(e)(t,n,r),dn=/^[cC][^\s-]{8,}$/,fn=/^[0-9a-z]+$/,pn=/^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/,gn=/^[0-9a-vA-V]{20}$/,hn=/^[A-Za-z0-9]{27}$/,mn=/^[a-zA-Z0-9_-]{21}$/,yn=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/,_n=/^([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})$/,wn=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)$/,vn=/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/;const kn=/^(?:(?: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])$/,bn=/^(([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}|:))$/,Sn=/^((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])$/,$n=/^(([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])$/,zn=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,jn=/^[A-Za-z0-9_-]*$/,xn=/^(?=.{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])?)*\.?$/,En=/^\+(?:[0-9]){6,14}[0-9]$/,An="(?:(?:\\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])))",Pn=new RegExp(`^${An}$`);function On(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 In=/^(?:true|false)$/i,Zn=/^[^A-Z]*$/,Tn=/^[^a-z]*$/,Nn=_t("$ZodCheck",(e,t)=>{var n;e._zod??(e._zod={}),e._zod.def=t,(n=e._zod).onattach??(n.onattach=[])}),Fn=_t("$ZodCheckMaxLength",(e,t)=>{var n;Nn.init(e,t),(n=e._zod.def).when??(n.when=e=>{const t=e.value;return!zt(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 o=Lt(r);n.issues.push({origin:o,code:"too_big",maximum:t.maximum,inclusive:!0,input:r,inst:e,continue:!t.abort})}}),Cn=_t("$ZodCheckMinLength",(e,t)=>{var n;Nn.init(e,t),(n=e._zod.def).when??(n.when=e=>{const t=e.value;return!zt(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 o=Lt(r);n.issues.push({origin:o,code:"too_small",minimum:t.minimum,inclusive:!0,input:r,inst:e,continue:!t.abort})}}),Dn=_t("$ZodCheckLengthEquals",(e,t)=>{var n;Nn.init(e,t),(n=e._zod.def).when??(n.when=e=>{const t=e.value;return!zt(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,o=r.length;if(o===t.length)return;const i=Lt(r),s=o>t.length;n.issues.push({origin:i,...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})}}),Un=_t("$ZodCheckStringFormat",(e,t)=>{var n,r;Nn.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=()=>{})}),Bn=_t("$ZodCheckRegex",(e,t)=>{Un.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})}}),Mn=_t("$ZodCheckLowerCase",(e,t)=>{t.pattern??(t.pattern=Zn),Un.init(e,t)}),Rn=_t("$ZodCheckUpperCase",(e,t)=>{t.pattern??(t.pattern=Tn),Un.init(e,t)}),Wn=_t("$ZodCheckIncludes",(e,t)=>{Nn.init(e,t);const n=Dt(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})}}),qn=_t("$ZodCheckStartsWith",(e,t)=>{Nn.init(e,t);const n=new RegExp(`^${Dt(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})}}),Ln=_t("$ZodCheckEndsWith",(e,t)=>{Nn.init(e,t);const n=new RegExp(`.*${Dt(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})}}),Jn=_t("$ZodCheckOverwrite",(e,t)=>{Nn.init(e,t),e._zod.check=e=>{e.value=t.tx(e.value)}});class Vn{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 Gn={major:4,minor:1,patch:12},Hn=_t("$ZodType",(e,t)=>{var n;e??(e={}),e._zod.def=t,e._zod.bag=e._zod.bag||{},e._zod.version=Gn;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,o=Mt(e);for(const i of t){if(i._zod.def.when){if(!i._zod.def.when(e))continue}else if(o)continue;const t=e.issues.length,s=i._zod.check(e);if(s instanceof Promise&&!1===n?.async)throw new wt;if(r||s instanceof Promise)r=(r??Promise.resolve()).then(async()=>{await s;e.issues.length!==t&&(o||(o=Mt(e,t)))});else{if(e.issues.length===t)continue;o||(o=Mt(e,t))}}return r?r.then(()=>e):e},n=(n,o,i)=>{if(Mt(n))return n.aborted=!0,n;const s=t(o,r,i);if(s instanceof Promise){if(!1===i.async)throw new wt;return s.then(t=>e._zod.parse(t,i))}return e._zod.parse(s,i)};e._zod.run=(o,i)=>{if(i.skipChecks)return e._zod.parse(o,i);if("backward"===i.direction){const t=e._zod.parse({value:o.value,issues:[]},{...i,skipChecks:!0});return t instanceof Promise?t.then(e=>n(e,o,i)):n(t,o,i)}const s=e._zod.parse(o,i);if(s instanceof Promise){if(!1===i.async)throw new wt;return s.then(e=>t(e,r,i))}return t(s,r,i)}}e["~standard"]={validate:t=>{try{const n=Qt(e,t);return n.success?{value:n.data}:{issues:n.error?.issues}}catch(n){return tn(e,t).then(e=>e.success?{value:e.data}:{issues:e.error?.issues})}},vendor:"zod",version:1}}),Kn=_t("$ZodString",(e,t)=>{var n;Hn.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}}),Xn=_t("$ZodStringFormat",(e,t)=>{Un.init(e,t),Kn.init(e,t)}),Yn=_t("$ZodGUID",(e,t)=>{t.pattern??(t.pattern=_n),Xn.init(e,t)}),Qn=_t("$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=wn(e))}else t.pattern??(t.pattern=wn());Xn.init(e,t)}),er=_t("$ZodEmail",(e,t)=>{t.pattern??(t.pattern=vn),Xn.init(e,t)}),tr=_t("$ZodURL",(e,t)=>{Xn.init(e,t),e._zod.check=n=>{try{const r=n.value.trim(),o=new URL(r);return t.hostname&&(t.hostname.lastIndex=0,t.hostname.test(o.hostname)||n.issues.push({code:"invalid_format",format:"url",note:"Invalid hostname",pattern:xn.source,input:n.value,inst:e,continue:!t.abort})),t.protocol&&(t.protocol.lastIndex=0,t.protocol.test(o.protocol.endsWith(":")?o.protocol.slice(0,-1):o.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=o.href:n.value=r)}catch(r){n.issues.push({code:"invalid_format",format:"url",input:n.value,inst:e,continue:!t.abort})}}}),nr=_t("$ZodEmoji",(e,t)=>{t.pattern??(t.pattern=new RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$","u")),Xn.init(e,t)}),rr=_t("$ZodNanoID",(e,t)=>{t.pattern??(t.pattern=mn),Xn.init(e,t)}),or=_t("$ZodCUID",(e,t)=>{t.pattern??(t.pattern=dn),Xn.init(e,t)}),ir=_t("$ZodCUID2",(e,t)=>{t.pattern??(t.pattern=fn),Xn.init(e,t)}),sr=_t("$ZodULID",(e,t)=>{t.pattern??(t.pattern=pn),Xn.init(e,t)}),ar=_t("$ZodXID",(e,t)=>{t.pattern??(t.pattern=gn),Xn.init(e,t)}),cr=_t("$ZodKSUID",(e,t)=>{t.pattern??(t.pattern=hn),Xn.init(e,t)}),lr=_t("$ZodISODateTime",(e,t)=>{t.pattern??(t.pattern=function(e){const t=On({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(`^${An}T(?:${r})$`)}(t)),Xn.init(e,t)}),ur=_t("$ZodISODate",(e,t)=>{t.pattern??(t.pattern=Pn),Xn.init(e,t)}),dr=_t("$ZodISOTime",(e,t)=>{t.pattern??(t.pattern=new RegExp(`^${On(t)}$`)),Xn.init(e,t)}),fr=_t("$ZodISODuration",(e,t)=>{t.pattern??(t.pattern=yn),Xn.init(e,t)}),pr=_t("$ZodIPv4",(e,t)=>{t.pattern??(t.pattern=kn),Xn.init(e,t),e._zod.onattach.push(e=>{e._zod.bag.format="ipv4"})}),gr=_t("$ZodIPv6",(e,t)=>{t.pattern??(t.pattern=bn),Xn.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})}}}),hr=_t("$ZodCIDRv4",(e,t)=>{t.pattern??(t.pattern=Sn),Xn.init(e,t)}),mr=_t("$ZodCIDRv6",(e,t)=>{t.pattern??(t.pattern=$n),Xn.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 yr(e){if(""===e)return!0;if(e.length%4!=0)return!1;try{return atob(e),!0}catch{return!1}}const _r=_t("$ZodBase64",(e,t)=>{t.pattern??(t.pattern=zn),Xn.init(e,t),e._zod.onattach.push(e=>{e._zod.bag.contentEncoding="base64"}),e._zod.check=n=>{yr(n.value)||n.issues.push({code:"invalid_format",format:"base64",input:n.value,inst:e,continue:!t.abort})}});const wr=_t("$ZodBase64URL",(e,t)=>{t.pattern??(t.pattern=jn),Xn.init(e,t),e._zod.onattach.push(e=>{e._zod.bag.contentEncoding="base64url"}),e._zod.check=n=>{(function(e){if(!jn.test(e))return!1;const t=e.replace(/[-_]/g,e=>"-"===e?"+":"/");return yr(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})}}),vr=_t("$ZodE164",(e,t)=>{t.pattern??(t.pattern=En),Xn.init(e,t)});const kr=_t("$ZodJWT",(e,t)=>{Xn.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 o=JSON.parse(atob(r));return!("typ"in o&&"JWT"!==o?.typ||!o.alg||t&&(!("alg"in o)||o.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})}}),br=_t("$ZodBoolean",(e,t)=>{Hn.init(e,t),e._zod.pattern=In,e._zod.parse=(n,r)=>{if(t.coerce)try{n.value=Boolean(n.value)}catch(e){}const o=n.value;return"boolean"==typeof o||n.issues.push({expected:"boolean",code:"invalid_type",input:o,inst:e}),n}}),Sr=_t("$ZodUnknown",(e,t)=>{Hn.init(e,t),e._zod.parse=e=>e}),$r=_t("$ZodNever",(e,t)=>{Hn.init(e,t),e._zod.parse=(t,n)=>(t.issues.push({expected:"never",code:"invalid_type",input:t.value,inst:e}),t)});function zr(e,t,n){e.issues.length&&t.issues.push(...Rt(n,e.issues)),t.value[n]=e.value}const jr=_t("$ZodArray",(e,t)=>{Hn.init(e,t),e._zod.parse=(n,r)=>{const o=n.value;if(!Array.isArray(o))return n.issues.push({expected:"array",code:"invalid_type",input:o,inst:e}),n;n.value=Array(o.length);const i=[];for(let e=0;e<o.length;e++){const s=o[e],a=t.element._zod.run({value:s,issues:[]},r);a instanceof Promise?i.push(a.then(t=>zr(t,n,e))):zr(a,n,e)}return i.length?Promise.all(i).then(()=>n):n}});function xr(e,t,n,r){e.issues.length&&t.issues.push(...Rt(n,e.issues)),void 0===e.value?n in r&&(t.value[n]=void 0):t.value[n]=e.value}function Er(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 Ar(e,t,n,r,o,i){const s=[],a=o.keySet,c=o.catchall._zod,l=c.def.type;for(const o of Object.keys(t)){if(a.has(o))continue;if("never"===l){s.push(o);continue}const i=c.run({value:t[o],issues:[]},r);i instanceof Promise?e.push(i.then(e=>xr(e,n,o,t))):xr(i,n,o,t)}return s.length&&n.issues.push({code:"unrecognized_keys",keys:s,input:t,inst:i}),e.length?Promise.all(e).then(()=>n):n}const Pr=_t("$ZodObject",(e,t)=>{Hn.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=$t(()=>Er(t));Et(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 o=Zt,i=t.catchall;let s;e._zod.parse=(t,n)=>{s??(s=r.value);const a=t.value;if(!o(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=>xr(n,t,e,a))):xr(r,t,e,a)}return i?Ar(c,a,t,n,r.value,e):c.length?Promise.all(c).then(()=>t):t}}),Or=_t("$ZodObjectJIT",(e,t)=>{Pr.init(e,t);const n=e._zod.parse,r=$t(()=>Er(t));let o;const i=Zt,s=!kt.jitless,a=s&&Tt.value,c=t.catchall;let l;e._zod.parse=(u,d)=>{l??(l=r.value);const f=u.value;return i(f)?s&&a&&!1===d?.async&&!0!==d.jitless?(o||(o=(e=>{const t=new Vn(["shape","payload","ctx"]),n=r.value,o=e=>{const t=Ot(e);return`shape[${t}]._zod.run({ value: input[${t}], issues: [] }, ctx)`};t.write("const input = payload.value;");const i=Object.create(null);let s=0;for(const e of n.keys)i[e]="key_"+s++;t.write("const newResult = {};");for(const e of n.keys){const n=i[e],r=Ot(e);t.write(`const ${n} = ${o(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=o(u,d),c?Ar([],f,u,d,l,e):u):n(u,d):(u.issues.push({expected:"object",code:"invalid_type",input:f,inst:e}),u)}});function Ir(e,t,n,r){for(const n of e)if(0===n.issues.length)return t.value=n.value,t;const o=e.filter(e=>!Mt(e));return 1===o.length?(t.value=o[0].value,o[0]):(t.issues.push({code:"invalid_union",input:t.value,inst:n,errors:e.map(e=>e.issues.map(e=>qt(e,r,bt())))}),t)}const Zr=_t("$ZodUnion",(e,t)=>{Hn.init(e,t),Et(e._zod,"optin",()=>t.options.some(e=>"optional"===e._zod.optin)?"optional":void 0),Et(e._zod,"optout",()=>t.options.some(e=>"optional"===e._zod.optout)?"optional":void 0),Et(e._zod,"values",()=>{if(t.options.every(e=>e._zod.values))return new Set(t.options.flatMap(e=>Array.from(e._zod.values)))}),Et(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=>jt(e.source)).join("|")})$`)}});const n=1===t.options.length,r=t.options[0]._zod.run;e._zod.parse=(o,i)=>{if(n)return r(o,i);let s=!1;const a=[];for(const e of t.options){const t=e._zod.run({value:o.value,issues:[]},i);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=>Ir(t,o,e,i)):Ir(a,o,e,i)}}),Tr=_t("$ZodIntersection",(e,t)=>{Hn.init(e,t),e._zod.parse=(e,n)=>{const r=e.value,o=t.left._zod.run({value:r,issues:[]},n),i=t.right._zod.run({value:r,issues:[]},n);return o instanceof Promise||i instanceof Promise?Promise.all([o,i]).then(([t,n])=>Fr(e,t,n)):Fr(e,o,i)}});function Nr(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(Nt(e)&&Nt(t)){const n=Object.keys(t),r=Object.keys(e).filter(e=>-1!==n.indexOf(e)),o={...e,...t};for(const n of r){const r=Nr(e[n],t[n]);if(!r.valid)return{valid:!1,mergeErrorPath:[n,...r.mergeErrorPath]};o[n]=r.data}return{valid:!0,data:o}}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 o=Nr(e[r],t[r]);if(!o.valid)return{valid:!1,mergeErrorPath:[r,...o.mergeErrorPath]};n.push(o.data)}return{valid:!0,data:n}}return{valid:!1,mergeErrorPath:[]}}function Fr(e,t,n){if(t.issues.length&&e.issues.push(...t.issues),n.issues.length&&e.issues.push(...n.issues),Mt(e))return e;const r=Nr(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 Cr=_t("$ZodRecord",(e,t)=>{Hn.init(e,t),e._zod.parse=(n,r)=>{const o=n.value;if(!Nt(o))return n.issues.push({expected:"record",code:"invalid_type",input:o,inst:e}),n;const i=[];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:o[e],issues:[]},r);s instanceof Promise?i.push(s.then(t=>{t.issues.length&&n.issues.push(...Rt(e,t.issues)),n.value[e]=t.value})):(s.issues.length&&n.issues.push(...Rt(e,s.issues)),n.value[e]=s.value)}let a;for(const e in o)s.has(e)||(a=a??[],a.push(e));a&&a.length>0&&n.issues.push({code:"unrecognized_keys",input:o,inst:e,keys:a})}else{n.value={};for(const s of Reflect.ownKeys(o)){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=>qt(e,r,bt())),input:s,path:[s],inst:e}),n.value[a.value]=a.value;continue}const c=t.valueType._zod.run({value:o[s],issues:[]},r);c instanceof Promise?i.push(c.then(e=>{e.issues.length&&n.issues.push(...Rt(s,e.issues)),n.value[a.value]=e.value})):(c.issues.length&&n.issues.push(...Rt(s,c.issues)),n.value[a.value]=c.value)}}return i.length?Promise.all(i).then(()=>n):n}}),Dr=_t("$ZodEnum",(e,t)=>{Hn.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=>Ct.has(typeof e)).map(e=>"string"==typeof e?Dt(e):e.toString()).join("|")})$`),e._zod.parse=(t,o)=>{const i=t.value;return r.has(i)||t.issues.push({code:"invalid_value",values:n,input:i,inst:e}),t}}),Ur=_t("$ZodLiteral",(e,t)=>{if(Hn.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?Dt(e):e?Dt(e.toString()):String(e)).join("|")})$`),e._zod.parse=(n,r)=>{const o=n.value;return e._zod.values.has(o)||n.issues.push({code:"invalid_value",values:t.values,input:o,inst:e}),n}}),Br=_t("$ZodTransform",(e,t)=>{Hn.init(e,t),e._zod.parse=(n,r)=>{if("backward"===r.direction)throw new vt(e.constructor.name);const o=t.transform(n.value,n);if(r.async){return(o instanceof Promise?o:Promise.resolve(o)).then(e=>(n.value=e,n))}if(o instanceof Promise)throw new wt;return n.value=o,n}});function Mr(e,t){return e.issues.length&&void 0===t?{issues:[],value:void 0}:e}const Rr=_t("$ZodOptional",(e,t)=>{Hn.init(e,t),e._zod.optin="optional",e._zod.optout="optional",Et(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),Et(e._zod,"pattern",()=>{const e=t.innerType._zod.pattern;return e?new RegExp(`^(${jt(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=>Mr(t,e.value)):Mr(r,e.value)}return void 0===e.value?e:t.innerType._zod.run(e,n)}}),Wr=_t("$ZodNullable",(e,t)=>{Hn.init(e,t),Et(e._zod,"optin",()=>t.innerType._zod.optin),Et(e._zod,"optout",()=>t.innerType._zod.optout),Et(e._zod,"pattern",()=>{const e=t.innerType._zod.pattern;return e?new RegExp(`^(${jt(e.source)}|null)$`):void 0}),Et(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)}),qr=_t("$ZodDefault",(e,t)=>{Hn.init(e,t),e._zod.optin="optional",Et(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=>Lr(e,t)):Lr(r,t)}});function Lr(e,t){return void 0===e.value&&(e.value=t.defaultValue),e}const Jr=_t("$ZodPrefault",(e,t)=>{Hn.init(e,t),e._zod.optin="optional",Et(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))}),Vr=_t("$ZodNonOptional",(e,t)=>{Hn.init(e,t),Et(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 o=t.innerType._zod.run(n,r);return o instanceof Promise?o.then(t=>Gr(t,e)):Gr(o,e)}});function Gr(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 Hr=_t("$ZodCatch",(e,t)=>{Hn.init(e,t),Et(e._zod,"optin",()=>t.innerType._zod.optin),Et(e._zod,"optout",()=>t.innerType._zod.optout),Et(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=>qt(e,n,bt()))},input:e.value}),e.issues=[]),e)):(e.value=r.value,r.issues.length&&(e.value=t.catchValue({...e,error:{issues:r.issues.map(e=>qt(e,n,bt()))},input:e.value}),e.issues=[]),e)}}),Kr=_t("$ZodPipe",(e,t)=>{Hn.init(e,t),Et(e._zod,"values",()=>t.in._zod.values),Et(e._zod,"optin",()=>t.in._zod.optin),Et(e._zod,"optout",()=>t.out._zod.optout),Et(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=>Xr(e,t.in,n)):Xr(r,t.in,n)}const r=t.in._zod.run(e,n);return r instanceof Promise?r.then(e=>Xr(e,t.out,n)):Xr(r,t.out,n)}});function Xr(e,t,n){return e.issues.length?(e.aborted=!0,e):t._zod.run({value:e.value,issues:e.issues},n)}const Yr=_t("$ZodReadonly",(e,t)=>{Hn.init(e,t),Et(e._zod,"propValues",()=>t.innerType._zod.propValues),Et(e._zod,"values",()=>t.innerType._zod.values),Et(e._zod,"optin",()=>t.innerType._zod.optin),Et(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(Qr):Qr(r)}});function Qr(e){return e.value=Object.freeze(e.value),e}const eo=_t("$ZodCustom",(e,t)=>{Nn.init(e,t),Hn.init(e,t),e._zod.parse=(e,t)=>e,e._zod.check=n=>{const r=n.value,o=t.fn(r);if(o instanceof Promise)return o.then(t=>to(t,n,r,e));to(o,n,r,e)}});function to(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(Jt(e))}}class no{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 ro(){return new no}const oo=ro();function io(e,t){return new e({type:"string",format:"guid",check:"string_format",abort:!1,...Bt(t)})}function so(e,t){return new Fn({check:"max_length",...Bt(t),maximum:e})}function ao(e,t){return new Cn({check:"min_length",...Bt(t),minimum:e})}function co(e,t){return new Dn({check:"length_equals",...Bt(t),length:e})}function lo(e){return new Jn({check:"overwrite",tx:e})}function uo(e){const t=function(e,t){const n=new Nn({check:"custom",...Bt(t)});return n._zod.check=e,n}(n=>(n.addIssue=e=>{if("string"==typeof e)n.issues.push(Jt(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(Jt(r))}},e(n.value,n)));return t}const fo=_t("ZodISODateTime",(e,t)=>{lr.init(e,t),Co.init(e,t)});function po(e){return function(e,t){return new e({type:"string",format:"datetime",check:"string_format",offset:!1,local:!1,precision:null,...Bt(t)})}(fo,e)}const go=_t("ZodISODate",(e,t)=>{ur.init(e,t),Co.init(e,t)});function ho(e){return function(e,t){return new e({type:"string",format:"date",check:"string_format",...Bt(t)})}(go,e)}const mo=_t("ZodISOTime",(e,t)=>{dr.init(e,t),Co.init(e,t)});function yo(e){return function(e,t){return new e({type:"string",format:"time",check:"string_format",precision:null,...Bt(t)})}(mo,e)}const _o=_t("ZodISODuration",(e,t)=>{fr.init(e,t),Co.init(e,t)});function wo(e){return function(e,t){return new e({type:"string",format:"duration",check:"string_format",...Bt(t)})}(_o,e)}const vo=_t("ZodError",(e,t)=>{Gt.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 o of e.issues)if("invalid_union"===o.code&&o.errors.length)o.errors.map(e=>r({issues:e}));else if("invalid_key"===o.code)r({issues:o.issues});else if("invalid_element"===o.code)r({issues:o.issues});else if(0===o.path.length)n._errors.push(t(o));else{let e=n,r=0;for(;r<o.path.length;){const n=o.path[r];r===o.path.length-1?(e[n]=e[n]||{_errors:[]},e[n]._errors.push(t(o))):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 o of e.issues)o.path.length>0?(n[o.path[0]]=n[o.path[0]]||[],n[o.path[0]].push(t(o))):r.push(t(o));return{formErrors:r,fieldErrors:n}}(e,t)},addIssue:{value:t=>{e.issues.push(t),e.message=JSON.stringify(e.issues,St,2)}},addIssues:{value:t=>{e.issues.push(...t),e.message=JSON.stringify(e.issues,St,2)}},isEmpty:{get:()=>0===e.issues.length}})},{Parent:Error}),ko=Kt(vo),bo=Xt(vo),So=Yt(vo),$o=en(vo),zo=nn(vo),jo=rn(vo),xo=on(vo),Eo=sn(vo),Ao=an(vo),Po=cn(vo),Oo=ln(vo),Io=un(vo),Zo=_t("ZodType",(e,t)=>(Hn.init(e,t),e.def=t,e.type=t.type,Object.defineProperty(e,"_def",{value:t}),e.check=(...n)=>e.clone(Pt(t,{checks:[...t.checks??[],...n.map(e=>"function"==typeof e?{_zod:{check:e,def:{check:"custom"},onattach:[]}}:e)]})),e.clone=(t,n)=>Ut(e,t,n),e.brand=()=>e,e.register=(t,n)=>(t.add(e,n),e),e.parse=(t,n)=>ko(e,t,n,{callee:e.parse}),e.safeParse=(t,n)=>So(e,t,n),e.parseAsync=async(t,n)=>bo(e,t,n,{callee:e.parseAsync}),e.safeParseAsync=async(t,n)=>$o(e,t,n),e.spa=e.safeParseAsync,e.encode=(t,n)=>zo(e,t,n),e.decode=(t,n)=>jo(e,t,n),e.encodeAsync=async(t,n)=>xo(e,t,n),e.decodeAsync=async(t,n)=>Eo(e,t,n),e.safeEncode=(t,n)=>Ao(e,t,n),e.safeDecode=(t,n)=>Po(e,t,n),e.safeEncodeAsync=async(t,n)=>Oo(e,t,n),e.safeDecodeAsync=async(t,n)=>Io(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,...Bt(n)})}(Ti,e,t)}(t,n)),e.superRefine=t=>e.check(uo(t)),e.overwrite=t=>e.check(lo(t)),e.optional=()=>$i(e),e.nullable=()=>ji(e),e.nullish=()=>$i(ji(e)),e.nonoptional=t=>function(e,t){return new Ai({type:"nonoptional",innerType:e,...Bt(t)})}(e,t),e.array=()=>ui(e),e.or=t=>gi([e,t]),e.and=t=>new hi({type:"intersection",left:e,right:t}),e.transform=t=>Ii(e,new bi({type:"transform",transform:t})),e.default=t=>{return n=t,new xi({type:"default",innerType:e,get defaultValue(){return"function"==typeof n?n():Ft(n)}});var n},e.prefault=t=>{return n=t,new Ei({type:"prefault",innerType:e,get defaultValue(){return"function"==typeof n?n():Ft(n)}});var n},e.catch=t=>{return new Pi({type:"catch",innerType:e,catchValue:"function"==typeof(n=t)?n:()=>n});var n},e.pipe=t=>Ii(e,t),e.readonly=()=>new Zi({type:"readonly",innerType:e}),e.describe=t=>{const n=e.clone();return oo.add(n,{description:t}),n},Object.defineProperty(e,"description",{get:()=>oo.get(e)?.description,configurable:!0}),e.meta=(...t)=>{if(0===t.length)return oo.get(e);const n=e.clone();return oo.add(n,t[0]),n},e.isOptional=()=>e.safeParse(void 0).success,e.isNullable=()=>e.safeParse(null).success,e)),To=_t("_ZodString",(e,t)=>{Kn.init(e,t),Zo.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 Bn({check:"string_format",format:"regex",...Bt(t),pattern:e})}(...t)),e.includes=(...t)=>e.check(function(e,t){return new Wn({check:"string_format",format:"includes",...Bt(t),includes:e})}(...t)),e.startsWith=(...t)=>e.check(function(e,t){return new qn({check:"string_format",format:"starts_with",...Bt(t),prefix:e})}(...t)),e.endsWith=(...t)=>e.check(function(e,t){return new Ln({check:"string_format",format:"ends_with",...Bt(t),suffix:e})}(...t)),e.min=(...t)=>e.check(ao(...t)),e.max=(...t)=>e.check(so(...t)),e.length=(...t)=>e.check(co(...t)),e.nonempty=(...t)=>e.check(ao(1,...t)),e.lowercase=t=>e.check(function(e){return new Mn({check:"string_format",format:"lowercase",...Bt(e)})}(t)),e.uppercase=t=>e.check(function(e){return new Rn({check:"string_format",format:"uppercase",...Bt(e)})}(t)),e.trim=()=>e.check(lo(e=>e.trim())),e.normalize=(...t)=>e.check(function(e){return lo(t=>t.normalize(e))}(...t)),e.toLowerCase=()=>e.check(lo(e=>e.toLowerCase())),e.toUpperCase=()=>e.check(lo(e=>e.toUpperCase()))}),No=_t("ZodString",(e,t)=>{Kn.init(e,t),To.init(e,t),e.email=t=>e.check(function(e,t){return new e({type:"string",format:"email",check:"string_format",abort:!1,...Bt(t)})}(Do,t)),e.url=t=>e.check(function(e,t){return new e({type:"string",format:"url",check:"string_format",abort:!1,...Bt(t)})}(Mo,t)),e.jwt=t=>e.check(function(e,t){return new e({type:"string",format:"jwt",check:"string_format",abort:!1,...Bt(t)})}(ni,t)),e.emoji=t=>e.check(function(e,t){return new e({type:"string",format:"emoji",check:"string_format",abort:!1,...Bt(t)})}(Ro,t)),e.guid=t=>e.check(io(Uo,t)),e.uuid=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,...Bt(t)})}(Bo,t)),e.uuidv4=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v4",...Bt(t)})}(Bo,t)),e.uuidv6=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v6",...Bt(t)})}(Bo,t)),e.uuidv7=t=>e.check(function(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v7",...Bt(t)})}(Bo,t)),e.nanoid=t=>e.check(function(e,t){return new e({type:"string",format:"nanoid",check:"string_format",abort:!1,...Bt(t)})}(Wo,t)),e.guid=t=>e.check(io(Uo,t)),e.cuid=t=>e.check(function(e,t){return new e({type:"string",format:"cuid",check:"string_format",abort:!1,...Bt(t)})}(qo,t)),e.cuid2=t=>e.check(function(e,t){return new e({type:"string",format:"cuid2",check:"string_format",abort:!1,...Bt(t)})}(Lo,t)),e.ulid=t=>e.check(function(e,t){return new e({type:"string",format:"ulid",check:"string_format",abort:!1,...Bt(t)})}(Jo,t)),e.base64=t=>e.check(function(e,t){return new e({type:"string",format:"base64",check:"string_format",abort:!1,...Bt(t)})}(Qo,t)),e.base64url=t=>e.check(function(e,t){return new e({type:"string",format:"base64url",check:"string_format",abort:!1,...Bt(t)})}(ei,t)),e.xid=t=>e.check(function(e,t){return new e({type:"string",format:"xid",check:"string_format",abort:!1,...Bt(t)})}(Vo,t)),e.ksuid=t=>e.check(function(e,t){return new e({type:"string",format:"ksuid",check:"string_format",abort:!1,...Bt(t)})}(Go,t)),e.ipv4=t=>e.check(function(e,t){return new e({type:"string",format:"ipv4",check:"string_format",abort:!1,...Bt(t)})}(Ho,t)),e.ipv6=t=>e.check(function(e,t){return new e({type:"string",format:"ipv6",check:"string_format",abort:!1,...Bt(t)})}(Ko,t)),e.cidrv4=t=>e.check(function(e,t){return new e({type:"string",format:"cidrv4",check:"string_format",abort:!1,...Bt(t)})}(Xo,t)),e.cidrv6=t=>e.check(function(e,t){return new e({type:"string",format:"cidrv6",check:"string_format",abort:!1,...Bt(t)})}(Yo,t)),e.e164=t=>e.check(function(e,t){return new e({type:"string",format:"e164",check:"string_format",abort:!1,...Bt(t)})}(ti,t)),e.datetime=t=>e.check(po(t)),e.date=t=>e.check(ho(t)),e.time=t=>e.check(yo(t)),e.duration=t=>e.check(wo(t))});function Fo(e){return function(e,t){return new e({type:"string",...Bt(t)})}(No,e)}const Co=_t("ZodStringFormat",(e,t)=>{Xn.init(e,t),To.init(e,t)}),Do=_t("ZodEmail",(e,t)=>{er.init(e,t),Co.init(e,t)}),Uo=_t("ZodGUID",(e,t)=>{Yn.init(e,t),Co.init(e,t)}),Bo=_t("ZodUUID",(e,t)=>{Qn.init(e,t),Co.init(e,t)}),Mo=_t("ZodURL",(e,t)=>{tr.init(e,t),Co.init(e,t)}),Ro=_t("ZodEmoji",(e,t)=>{nr.init(e,t),Co.init(e,t)}),Wo=_t("ZodNanoID",(e,t)=>{rr.init(e,t),Co.init(e,t)}),qo=_t("ZodCUID",(e,t)=>{or.init(e,t),Co.init(e,t)}),Lo=_t("ZodCUID2",(e,t)=>{ir.init(e,t),Co.init(e,t)}),Jo=_t("ZodULID",(e,t)=>{sr.init(e,t),Co.init(e,t)}),Vo=_t("ZodXID",(e,t)=>{ar.init(e,t),Co.init(e,t)}),Go=_t("ZodKSUID",(e,t)=>{cr.init(e,t),Co.init(e,t)}),Ho=_t("ZodIPv4",(e,t)=>{pr.init(e,t),Co.init(e,t)}),Ko=_t("ZodIPv6",(e,t)=>{gr.init(e,t),Co.init(e,t)}),Xo=_t("ZodCIDRv4",(e,t)=>{hr.init(e,t),Co.init(e,t)}),Yo=_t("ZodCIDRv6",(e,t)=>{mr.init(e,t),Co.init(e,t)}),Qo=_t("ZodBase64",(e,t)=>{_r.init(e,t),Co.init(e,t)}),ei=_t("ZodBase64URL",(e,t)=>{wr.init(e,t),Co.init(e,t)}),ti=_t("ZodE164",(e,t)=>{vr.init(e,t),Co.init(e,t)}),ni=_t("ZodJWT",(e,t)=>{kr.init(e,t),Co.init(e,t)}),ri=_t("ZodBoolean",(e,t)=>{br.init(e,t),Zo.init(e,t)});function oi(e){return function(e,t){return new e({type:"boolean",...Bt(t)})}(ri,e)}const ii=_t("ZodUnknown",(e,t)=>{Sr.init(e,t),Zo.init(e,t)});function si(){return new ii({type:"unknown"})}const ai=_t("ZodNever",(e,t)=>{$r.init(e,t),Zo.init(e,t)});function ci(e){return function(e,t){return new e({type:"never",...Bt(t)})}(ai,e)}const li=_t("ZodArray",(e,t)=>{jr.init(e,t),Zo.init(e,t),e.element=t.element,e.min=(t,n)=>e.check(ao(t,n)),e.nonempty=t=>e.check(ao(1,t)),e.max=(t,n)=>e.check(so(t,n)),e.length=(t,n)=>e.check(co(t,n)),e.unwrap=()=>e.element});function ui(e,t){return function(e,t,n){return new e({type:"array",element:t,...Bt(n)})}(li,e,t)}const di=_t("ZodObject",(e,t)=>{Or.init(e,t),Zo.init(e,t),Et(e,"shape",()=>t.shape),e.keyof=()=>wi(Object.keys(e._zod.def.shape)),e.catchall=t=>e.clone({...e._zod.def,catchall:t}),e.passthrough=()=>e.clone({...e._zod.def,catchall:si()}),e.loose=()=>e.clone({...e._zod.def,catchall:si()}),e.strict=()=>e.clone({...e._zod.def,catchall:ci()}),e.strip=()=>e.clone({...e._zod.def,catchall:void 0}),e.extend=t=>function(e,t){if(!Nt(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=Pt(e._zod.def,{get shape(){const n={...e._zod.def.shape,...t};return At(this,"shape",n),n},checks:[]});return Ut(e,r)}(e,t),e.safeExtend=t=>function(e,t){if(!Nt(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 At(this,"shape",n),n},checks:e._zod.def.checks};return Ut(e,n)}(e,t),e.merge=t=>function(e,t){const n=Pt(e._zod.def,{get shape(){const n={...e._zod.def.shape,...t._zod.def.shape};return At(this,"shape",n),n},get catchall(){return t._zod.def.catchall},checks:[]});return Ut(e,n)}(e,t),e.pick=t=>function(e,t){const n=e._zod.def;return Ut(e,Pt(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 At(this,"shape",e),e},checks:[]}))}(e,t),e.omit=t=>function(e,t){const n=e._zod.def,r=Pt(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 At(this,"shape",r),r},checks:[]});return Ut(e,r)}(e,t),e.partial=(...t)=>function(e,t,n){const r=Pt(t._zod.def,{get shape(){const r=t._zod.def.shape,o={...r};if(n)for(const t in n){if(!(t in r))throw new Error(`Unrecognized key: "${t}"`);n[t]&&(o[t]=e?new e({type:"optional",innerType:r[t]}):r[t])}else for(const t in r)o[t]=e?new e({type:"optional",innerType:r[t]}):r[t];return At(this,"shape",o),o},checks:[]});return Ut(t,r)}(Si,e,t[0]),e.required=(...t)=>function(e,t,n){const r=Pt(t._zod.def,{get shape(){const r=t._zod.def.shape,o={...r};if(n)for(const t in n){if(!(t in o))throw new Error(`Unrecognized key: "${t}"`);n[t]&&(o[t]=new e({type:"nonoptional",innerType:r[t]}))}else for(const t in r)o[t]=new e({type:"nonoptional",innerType:r[t]});return At(this,"shape",o),o},checks:[]});return Ut(t,r)}(Ai,e,t[0])});function fi(e,t){const n={type:"object",shape:e??{},...Bt(t)};return new di(n)}const pi=_t("ZodUnion",(e,t)=>{Zr.init(e,t),Zo.init(e,t),e.options=t.options});function gi(e,t){return new pi({type:"union",options:e,...Bt(t)})}const hi=_t("ZodIntersection",(e,t)=>{Tr.init(e,t),Zo.init(e,t)});const mi=_t("ZodRecord",(e,t)=>{Cr.init(e,t),Zo.init(e,t),e.keyType=t.keyType,e.valueType=t.valueType});function yi(e,t,n){return new mi({type:"record",keyType:e,valueType:t,...Bt(n)})}const _i=_t("ZodEnum",(e,t)=>{Dr.init(e,t),Zo.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 o={};for(const r of e){if(!n.has(r))throw new Error(`Key ${r} not found in enum`);o[r]=t.entries[r]}return new _i({...t,checks:[],...Bt(r),entries:o})},e.exclude=(e,r)=>{const o={...t.entries};for(const t of e){if(!n.has(t))throw new Error(`Key ${t} not found in enum`);delete o[t]}return new _i({...t,checks:[],...Bt(r),entries:o})}});function wi(e,t){const n=Array.isArray(e)?Object.fromEntries(e.map(e=>[e,e])):e;return new _i({type:"enum",entries:n,...Bt(t)})}const vi=_t("ZodLiteral",(e,t)=>{Ur.init(e,t),Zo.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 ki(e,t){return new vi({type:"literal",values:Array.isArray(e)?e:[e],...Bt(t)})}const bi=_t("ZodTransform",(e,t)=>{Br.init(e,t),Zo.init(e,t),e._zod.parse=(n,r)=>{if("backward"===r.direction)throw new vt(e.constructor.name);n.addIssue=r=>{if("string"==typeof r)n.issues.push(Jt(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(Jt(t))}};const o=t.transform(n.value,n);return o instanceof Promise?o.then(e=>(n.value=e,n)):(n.value=o,n)}});const Si=_t("ZodOptional",(e,t)=>{Rr.init(e,t),Zo.init(e,t),e.unwrap=()=>e._zod.def.innerType});function $i(e){return new Si({type:"optional",innerType:e})}const zi=_t("ZodNullable",(e,t)=>{Wr.init(e,t),Zo.init(e,t),e.unwrap=()=>e._zod.def.innerType});function ji(e){return new zi({type:"nullable",innerType:e})}const xi=_t("ZodDefault",(e,t)=>{qr.init(e,t),Zo.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeDefault=e.unwrap});const Ei=_t("ZodPrefault",(e,t)=>{Jr.init(e,t),Zo.init(e,t),e.unwrap=()=>e._zod.def.innerType});const Ai=_t("ZodNonOptional",(e,t)=>{Vr.init(e,t),Zo.init(e,t),e.unwrap=()=>e._zod.def.innerType});const Pi=_t("ZodCatch",(e,t)=>{Hr.init(e,t),Zo.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeCatch=e.unwrap});const Oi=_t("ZodPipe",(e,t)=>{Kr.init(e,t),Zo.init(e,t),e.in=t.in,e.out=t.out});function Ii(e,t){return new Oi({type:"pipe",in:e,out:t})}const Zi=_t("ZodReadonly",(e,t)=>{Yr.init(e,t),Zo.init(e,t),e.unwrap=()=>e._zod.def.innerType});const Ti=_t("ZodCustom",(e,t)=>{eo.init(e,t),Zo.init(e,t)});const Ni="directus:extension",Fi=fi({app:Fo(),api:Fo()}),Ci=fi({request:$i(fi({urls:ui(Fo()),methods:ui(gi([ki("GET"),ki("POST"),ki("PATCH"),ki("PUT"),ki("DELETE")]))})),log:$i(fi({})),sleep:$i(fi({}))}),Di=$i(fi({enabled:oi(),requestedScopes:Ci})),Ui=gi([fi({type:wi(mt),name:Fo(),source:Fo()}),fi({type:wi(ht),name:Fo(),source:Fo()}),fi({type:wi(yt),name:Fo(),source:Fi})]),Bi=fi({host:Fo(),hidden:oi().optional()}),Mi=fi({type:wi(ht),path:Fo(),source:Fo()}),Ri=fi({type:wi(mt),path:Fo(),source:Fo(),sandbox:Di}),Wi=fi({type:wi(yt),path:Fi,source:Fi,sandbox:Di}),qi=fi({type:ki("bundle"),partial:oi().optional(),path:Fi,entries:ui(Ui)});ui(Ui);const Li=Bi.and(gi([Mi,Ri,Wi,qi]));fi({name:Fo(),version:Fo(),type:gi([ki("module"),ki("commonjs")]).optional(),description:Fo().optional(),icon:Fo().optional(),dependencies:yi(Fo(),Fo()).optional(),devDependencies:yi(Fo(),Fo()).optional(),[Ni]:Li});function Ji(e){return Object.entries(e).filter(([,e])=>Ve(e)&&Le(e.prefix_strategy)).map(([e])=>e)}async function Vi(e,t,n,r,o){if(n&&n!==r)for(const i of t)try{const t=await e("directus_files").count({c:"*"}).where("storage",i).whereRaw("filename_disk LIKE ?",[`${n}/%`]).first(),s=Number(t?.c??0);s>=100&&o.warn(`[storage-manager] Folder path sync on ${i}: relocating ${s} files (“${n}” → “${r||"(root)"}”) — this may take a while`);const{moved:a,failed:c}=await ce(e,i,n,r,o);(a||c)&&o.info(`[storage-manager] Folder path sync on ${i}: "${n}" → "${r||"(root)"}" (moved=${a}, failed=${c})`)}catch(e){o.error(`[storage-manager] Folder path sync failed for ${i}: ${e?.message}`)}}async function Gi(e,t,n){const r={},o={},i=await t("directus_folders").select("id","parent").where("id",e).first(),s=i?.parent?String(i.parent):null;for(const i of(a=n,Object.entries(a).filter(([,e])=>Ve(e)).map(([e])=>e))){const a=n[i];let c=null,l="";Le(a.prefix_strategy)?(c=await He(t,e),l=s&&await He(t,s)||""):Je(a.prefix_strategy)&&(c=await Ke(t,e),l=s&&await Ke(t,s)||""),c&&(r[i]=c,o[i]=l)}var a;return{folderPaths:r,parentPaths:o}}async function Hi(e,t,n){const r=await n("directus_folders").select("id","name","parent").where("id",e).first();if(!r)return null;const o=String(r.name);if(o===t)return null;const i=r.parent?String(r.parent):null,s=new Set([e,...await De(n,i,o),...await De(n,i,t)]),a={};for(const e of s){const t=await He(n,e);t&&(a[e]=t)}return a}async function Ki(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),o=n.parent?String(n.parent):null,i=(await De(t,o,r)).filter(t=>t!==e),s={};for(const e of i){const n=await He(t,e);n&&(s[e]=n)}return{parent:o,name:r,siblingOldPaths:s}}async function Xi(e,t,n,r,o){const i=Ji(r);if(i.length)for(const[e,r]of Object.entries(t)){const t=await He(n,e);t&&r&&t!==r&&await Vi(n,i,r,t,o)}}async function Yi(e,t,n,r){const o=Ji(n);if(o.length)for(const[n,i]of Object.entries(e)){const e=await He(t,n);e&&i&&e!==i&&await Vi(t,o,i,e,r)}}async function Qi(e,t,n,r,o,i){for(const[e,s]of Object.entries(t)){const t=o[e];if(!t||!Ve(t))continue;const a=n[e]??"";await Vi(r,[e],s,a,i)}}const es=[{name:"storage-manager-hook",config:({filter:e,action:t},{database:n,env:r,services:o,getSchema:i,logger:s})=>{t("server.start",async()=>{await Te(n,o,i,s)}),e("settings.update",e=>(Z in e&&Pe(),e)),e("files.create",async e=>{try{const t=String(r.STORAGE_LOCATIONS??"local").split(",").map(e=>e.trim()).filter(Boolean),o=String(e.storage??t[0]??"local"),i=Ze(await Oe(n),o);if(!Ve(i))return e;const s=await Ye(i,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("folders.create",async e=>{try{const t=e.keys??(e.key?[e.key]:[]);for(const e of t)await Me(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 Oe(n),o=Object.values(r.locations).some(e=>Ve(e)&&Le(e.prefix_strategy)),i=t.keys??(t.key?[t.key]:[]),s=String(e.name);for(const e of i){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}),!o)continue;const r=await Hi(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 Oe(n),r=e.keys??(e.key?[e.key]:[]);for(const e of r){const r=c.get(e);c.delete(e),r&&await Re(e,r.oldName,r.newName,r.parent,n,s);const o=a.get(e);a.delete(e),o&&await Xi(0,o,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 Oe(n),r=Object.values(t.locations).some(e=>Ve(e)),o=Object.values(t.locations).some(e=>Ve(e)&&Le(e.prefix_strategy));for(const i of e){const e=await qe(i,n);if(e&&d.set(i,e),!r)continue;const s=await Gi(i,n,t.locations);if(Object.keys(s.folderPaths).length&&l.set(i,s),o){const e=await Ki(i,n);e&&Object.keys(e.siblingOldPaths).length&&u.set(i,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 Oe(n);for(const r of t){const t=d.get(r);d.delete(r),t&&await We(r,t.parent,t.name,n,s);const o=l.get(r);l.delete(r),o&&await Qi(0,o.folderPaths,o.parentPaths,n,e.locations,s);const i=u.get(r);u.delete(r),i&&await Yi(i,n,e.locations,s)}}catch(e){s.error(`[storage-manager] Folder delete sync error: ${e?.message}`)}});const p=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),o=[];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&&o.push({id:String(e.id),storage:n,filename_disk:t})}return o}(n,e);for(const e of t)p.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=p.get(e);t&&(p.delete(e),n.push(t))}if(n.length)try{await async function(e,t){if(!e.length)return;const n=await f();for(const r of e)try{const e=n.location(r.storage);await $(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}`)}})}}],ts=[{name:"storage-manager-endpoint",config:pt}],ns=[{name:"storage-manager-operation",config:gt}];export{ts as endpoints,es as hooks,ns as operations};
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "directus-extension-storage-manager",
|
|
3
3
|
"description": "Browse, upload, detect, materialize, and move Directus files across storage adapters (local, S3, GCS, Azure, and more)",
|
|
4
4
|
"icon": "storage",
|
|
5
|
-
"version": "1.2.
|
|
5
|
+
"version": "1.2.2",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"directus",
|