directus-extension-key 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ankit Chauhan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # Directus Key Extension
2
+
3
+ A Directus **bundle extension** that provides centralized, secure management of API keys, access tokens, and encryption secrets. It prevents sensitive values from being exposed in configuration files or version control.
4
+
5
+ ## Features
6
+
7
+ - 🗄️ **4 Storage Providers** — Database (encrypted), File, Environment Variable, External (Vault/KMS)
8
+ - 🔐 **AES-256-GCM Encryption** — Database-stored values are encrypted using your Directus `SECRET`
9
+ - 🖥️ **Admin UI** — Vue 3 module in the Directus Data Studio sidebar
10
+ - 🔌 **REST API** — Full CRUD + secure retrieval endpoint
11
+ - 📦 **`getKey()` Helper** — Typed function for use in other Directus extensions
12
+
13
+ ## Project Structure
14
+
15
+ ```
16
+ src/
17
+ ├── api/
18
+ │ ├── hook/index.ts ← creates directus_keys table on startup
19
+ │ ├── endpoint/index.ts ← REST routes at /km/*
20
+ │ └── providers/
21
+ │ ├── index.ts ← getKey() helper + provider factory
22
+ │ ├── database.ts ← AES-256-GCM encrypt/decrypt
23
+ │ ├── file.ts ← reads from server file path
24
+ │ ├── env.ts ← reads from process.env
25
+ │ └── external.ts ← HTTP fetch (Vault / KMS)
26
+ └── module/
27
+ ├── index.ts ← Vue module registration
28
+ └── components/
29
+ ├── KeyList.vue ← table with provider badges + CRUD actions
30
+ └── KeyForm.vue ← drawer form with dynamic fields per provider
31
+ ```
32
+
33
+ ## Getting Started
34
+
35
+ ### 1. Build the Extension
36
+
37
+ ```bash
38
+ npm install
39
+ npm run build
40
+ ```
41
+
42
+ ### 2. Start Directus
43
+
44
+ The extension is auto-loaded via the mounted `extensions/` volume.
45
+
46
+ ```bash
47
+ cd ../../ # directus/
48
+ docker compose up
49
+ ```
50
+
51
+ ### 3. Use the Admin UI
52
+
53
+ Log in to `http://localhost:8055/admin` → click **Key Manager** in the left sidebar.
54
+
55
+ ## REST API
56
+
57
+ All routes require an admin Bearer token.
58
+
59
+ ```bash
60
+ # List all keys (values never exposed)
61
+ curl -H "Authorization: Bearer <token>" http://localhost:8055/km/keys
62
+
63
+ # Create an env-var key
64
+ curl -X POST -H "Authorization: Bearer <token>" \
65
+ -H "Content-Type: application/json" \
66
+ -d '{"name":"STRIPE_KEY","provider":"env","source":"STRIPE_SECRET"}' \
67
+ http://localhost:8055/km/keys
68
+
69
+ # Retrieve resolved secret
70
+ curl -H "Authorization: Bearer <token>" http://localhost:8055/km/retrieve/STRIPE_KEY
71
+ # → { "data": { "name": "STRIPE_KEY", "value": "sk_live_..." } }
72
+
73
+ # Update a key
74
+ curl -X PATCH -H "Authorization: Bearer <token>" \
75
+ -H "Content-Type: application/json" \
76
+ -d '{"description":"Updated description"}' \
77
+ http://localhost:8055/km/keys/<id>
78
+
79
+ # Delete a key
80
+ curl -X DELETE -H "Authorization: Bearer <token>" http://localhost:8055/km/keys/<id>
81
+ ```
82
+
83
+ ## Using `getKey()` in Other Extensions
84
+
85
+ ```typescript
86
+ import { getKey } from 'directus-extension-key-manager/src/api/providers/index.js';
87
+
88
+ // Inside any hook or endpoint that has the `database` knex instance:
89
+ const stripeSecret = await getKey('STRIPE_KEY', database);
90
+ ```
91
+
92
+ ## Storage Providers
93
+
94
+ | Provider | How it resolves the value | Recommended for |
95
+ |---|---|---|
96
+ | `database` | Decrypts AES-256-GCM value from DB | Development / low-risk |
97
+ | `file` | Reads from absolute file path on server | Staging / production |
98
+ | `env` | Returns `process.env[varName]` | CI/CD / containers |
99
+ | `external` | HTTP GET to Vault / KMS URL | Production / enterprise |
100
+
101
+ ### External Provider
102
+
103
+ Set `KM_EXTERNAL_TOKEN` env var to send a `Authorization: Bearer` header to your external endpoint.
104
+
105
+ Supported response shapes:
106
+ - `{ "value": "..." }` — generic
107
+ - `{ "data": { "value": "..." } }` — HashiCorp Vault KV v2
108
+ - `{ "SecretString": "..." }` — AWS Secrets Manager
109
+
110
+ ## Security Notes
111
+
112
+ > **Warning**: If the Directus `SECRET` env var is rotated, all **database-provider** keys must be re-created, as the old ciphertext cannot be decrypted with a new key.
113
+
114
+ - Raw secret values are **never** returned by the `GET /km/keys` list endpoint
115
+ - All endpoints require `admin` role authentication
116
+ - For production, prefer `file`, `env`, or `external` providers over `database`
package/dist/api.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";var e,t,a=require("crypto"),r=require("fs/promises");!function(e){e.assertEqual=e=>e,e.assertIs=function(e){},e.assertNever=function(e){throw new Error},e.arrayToEnum=e=>{const t={};for(const a of e)t[a]=a;return t},e.getValidEnumValues=t=>{const a=e.objectKeys(t).filter(e=>"number"!=typeof t[t[e]]),r={};for(const e of a)r[e]=t[e];return e.objectValues(r)},e.objectValues=t=>e.objectKeys(t).map(function(e){return t[e]}),e.objectKeys="function"==typeof Object.keys?e=>Object.keys(e):e=>{const t=[];for(const a in e)Object.prototype.hasOwnProperty.call(e,a)&&t.push(a);return t},e.find=(e,t)=>{for(const a of e)if(t(a))return a},e.isInteger="function"==typeof Number.isInteger?e=>Number.isInteger(e):e=>"number"==typeof e&&isFinite(e)&&Math.floor(e)===e,e.joinValues=function(e,t=" | "){return e.map(e=>"string"==typeof e?`'${e}'`:e).join(t)},e.jsonStringifyReplacer=(e,t)=>"bigint"==typeof t?t.toString():t}(e||(e={})),function(e){e.mergeShapes=(e,t)=>({...e,...t})}(t||(t={}));const s=e.arrayToEnum(["string","nan","number","integer","float","boolean","date","bigint","symbol","function","undefined","null","array","object","unknown","promise","void","never","map","set"]),n=e=>{switch(typeof e){case"undefined":return s.undefined;case"string":return s.string;case"number":return isNaN(e)?s.nan:s.number;case"boolean":return s.boolean;case"function":return s.function;case"bigint":return s.bigint;case"symbol":return s.symbol;case"object":return Array.isArray(e)?s.array:null===e?s.null:e.then&&"function"==typeof e.then&&e.catch&&"function"==typeof e.catch?s.promise:"undefined"!=typeof Map&&e instanceof Map?s.map:"undefined"!=typeof Set&&e instanceof Set?s.set:"undefined"!=typeof Date&&e instanceof Date?s.date:s.object;default:return s.unknown}},i=e.arrayToEnum(["invalid_type","invalid_literal","custom","invalid_union","invalid_union_discriminator","invalid_enum_value","unrecognized_keys","invalid_arguments","invalid_return_type","invalid_date","invalid_string","too_small","too_big","invalid_intersection_types","not_multiple_of","not_finite"]);class o extends Error{constructor(e){super(),this.issues=[],this.addIssue=e=>{this.issues=[...this.issues,e]},this.addIssues=(e=[])=>{this.issues=[...this.issues,...e]};const t=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,t):this.__proto__=t,this.name="ZodError",this.issues=e}get errors(){return this.issues}format(e){const t=e||function(e){return e.message},a={_errors:[]},r=e=>{for(const s of e.issues)if("invalid_union"===s.code)s.unionErrors.map(r);else if("invalid_return_type"===s.code)r(s.returnTypeError);else if("invalid_arguments"===s.code)r(s.argumentsError);else if(0===s.path.length)a._errors.push(t(s));else{let e=a,r=0;for(;r<s.path.length;){const a=s.path[r];r===s.path.length-1?(e[a]=e[a]||{_errors:[]},e[a]._errors.push(t(s))):e[a]=e[a]||{_errors:[]},e=e[a],r++}}};return r(this),a}static assert(e){if(!(e instanceof o))throw new Error(`Not a ZodError: ${e}`)}toString(){return this.message}get message(){return JSON.stringify(this.issues,e.jsonStringifyReplacer,2)}get isEmpty(){return 0===this.issues.length}flatten(e=e=>e.message){const t={},a=[];for(const r of this.issues)r.path.length>0?(t[r.path[0]]=t[r.path[0]]||[],t[r.path[0]].push(e(r))):a.push(e(r));return{formErrors:a,fieldErrors:t}}get formErrors(){return this.flatten()}}o.create=e=>new o(e);const d=(t,a)=>{let r;switch(t.code){case i.invalid_type:r=t.received===s.undefined?"Required":`Expected ${t.expected}, received ${t.received}`;break;case i.invalid_literal:r=`Invalid literal value, expected ${JSON.stringify(t.expected,e.jsonStringifyReplacer)}`;break;case i.unrecognized_keys:r=`Unrecognized key(s) in object: ${e.joinValues(t.keys,", ")}`;break;case i.invalid_union:r="Invalid input";break;case i.invalid_union_discriminator:r=`Invalid discriminator value. Expected ${e.joinValues(t.options)}`;break;case i.invalid_enum_value:r=`Invalid enum value. Expected ${e.joinValues(t.options)}, received '${t.received}'`;break;case i.invalid_arguments:r="Invalid function arguments";break;case i.invalid_return_type:r="Invalid function return type";break;case i.invalid_date:r="Invalid date";break;case i.invalid_string:"object"==typeof t.validation?"includes"in t.validation?(r=`Invalid input: must include "${t.validation.includes}"`,"number"==typeof t.validation.position&&(r=`${r} at one or more positions greater than or equal to ${t.validation.position}`)):"startsWith"in t.validation?r=`Invalid input: must start with "${t.validation.startsWith}"`:"endsWith"in t.validation?r=`Invalid input: must end with "${t.validation.endsWith}"`:e.assertNever(t.validation):r="regex"!==t.validation?`Invalid ${t.validation}`:"Invalid";break;case i.too_small:r="array"===t.type?`Array must contain ${t.exact?"exactly":t.inclusive?"at least":"more than"} ${t.minimum} element(s)`:"string"===t.type?`String must contain ${t.exact?"exactly":t.inclusive?"at least":"over"} ${t.minimum} character(s)`:"number"===t.type?`Number must be ${t.exact?"exactly equal to ":t.inclusive?"greater than or equal to ":"greater than "}${t.minimum}`:"date"===t.type?`Date must be ${t.exact?"exactly equal to ":t.inclusive?"greater than or equal to ":"greater than "}${new Date(Number(t.minimum))}`:"Invalid input";break;case i.too_big:r="array"===t.type?`Array must contain ${t.exact?"exactly":t.inclusive?"at most":"less than"} ${t.maximum} element(s)`:"string"===t.type?`String must contain ${t.exact?"exactly":t.inclusive?"at most":"under"} ${t.maximum} character(s)`:"number"===t.type?`Number must be ${t.exact?"exactly":t.inclusive?"less than or equal to":"less than"} ${t.maximum}`:"bigint"===t.type?`BigInt must be ${t.exact?"exactly":t.inclusive?"less than or equal to":"less than"} ${t.maximum}`:"date"===t.type?`Date must be ${t.exact?"exactly":t.inclusive?"smaller than or equal to":"smaller than"} ${new Date(Number(t.maximum))}`:"Invalid input";break;case i.custom:r="Invalid input";break;case i.invalid_intersection_types:r="Intersection results could not be merged";break;case i.not_multiple_of:r=`Number must be a multiple of ${t.multipleOf}`;break;case i.not_finite:r="Number must be finite";break;default:r=a.defaultError,e.assertNever(t)}return{message:r}};let u=d;function c(){return u}const l=e=>{const{data:t,path:a,errorMaps:r,issueData:s}=e,n=[...a,...s.path||[]],i={...s,path:n};if(void 0!==s.message)return{...s,path:n,message:s.message};let o="";const d=r.filter(e=>!!e).slice().reverse();for(const e of d)o=e(i,{data:t,defaultError:o}).message;return{...s,path:n,message:o}};function p(e,t){const a=c(),r=l({issueData:t,data:e.data,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,a,a===d?void 0:d].filter(e=>!!e)});e.common.issues.push(r)}class h{constructor(){this.value="valid"}dirty(){"valid"===this.value&&(this.value="dirty")}abort(){"aborted"!==this.value&&(this.value="aborted")}static mergeArray(e,t){const a=[];for(const r of t){if("aborted"===r.status)return m;"dirty"===r.status&&e.dirty(),a.push(r.value)}return{status:e.value,value:a}}static async mergeObjectAsync(e,t){const a=[];for(const e of t){const t=await e.key,r=await e.value;a.push({key:t,value:r})}return h.mergeObjectSync(e,a)}static mergeObjectSync(e,t){const a={};for(const r of t){const{key:t,value:s}=r;if("aborted"===t.status)return m;if("aborted"===s.status)return m;"dirty"===t.status&&e.dirty(),"dirty"===s.status&&e.dirty(),"__proto__"===t.value||void 0===s.value&&!r.alwaysSet||(a[t.value]=s.value)}return{status:e.value,value:a}}}const m=Object.freeze({status:"aborted"}),f=e=>({status:"dirty",value:e}),y=e=>({status:"valid",value:e}),v=e=>"aborted"===e.status,g=e=>"dirty"===e.status,_=e=>"valid"===e.status,b=e=>"undefined"!=typeof Promise&&e instanceof Promise;function k(e,t,a,r){if("a"===a&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===a?r:"a"===a?r.call(e):r?r.value:t.get(e)}function x(e,t,a,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,a):s?s.value=a:t.set(e,a),a}var w,T,Z;"function"==typeof SuppressedError&&SuppressedError,function(e){e.errToObj=e=>"string"==typeof e?{message:e}:e||{},e.toString=e=>"string"==typeof e?e:null==e?void 0:e.message}(w||(w={}));class E{constructor(e,t,a,r){this._cachedPath=[],this.parent=e,this.data=t,this._path=a,this._key=r}get path(){return this._cachedPath.length||(this._key instanceof Array?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}}const j=(e,t)=>{if(_(t))return{success:!0,data:t.value};if(!e.common.issues.length)throw new Error("Validation failed but no issues detected.");return{success:!1,get error(){if(this._error)return this._error;const t=new o(e.common.issues);return this._error=t,this._error}}};function O(e){if(!e)return{};const{errorMap:t,invalid_type_error:a,required_error:r,description:s}=e;if(t&&(a||r))throw new Error('Can\'t use "invalid_type_error" or "required_error" in conjunction with custom error map.');if(t)return{errorMap:t,description:s};return{errorMap:(t,s)=>{var n,i;const{message:o}=e;return"invalid_enum_value"===t.code?{message:null!=o?o:s.defaultError}:void 0===s.data?{message:null!==(n=null!=o?o:r)&&void 0!==n?n:s.defaultError}:"invalid_type"!==t.code?{message:s.defaultError}:{message:null!==(i=null!=o?o:a)&&void 0!==i?i:s.defaultError}},description:s}}class C{constructor(e){this.spa=this.safeParseAsync,this._def=e,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this)}get description(){return this._def.description}_getType(e){return n(e.data)}_getOrReturnCtx(e,t){return t||{common:e.parent.common,data:e.data,parsedType:n(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}_processInputParams(e){return{status:new h,ctx:{common:e.parent.common,data:e.data,parsedType:n(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}}_parseSync(e){const t=this._parse(e);if(b(t))throw new Error("Synchronous parse encountered promise.");return t}_parseAsync(e){const t=this._parse(e);return Promise.resolve(t)}parse(e,t){const a=this.safeParse(e,t);if(a.success)return a.data;throw a.error}safeParse(e,t){var a;const r={common:{issues:[],async:null!==(a=null==t?void 0:t.async)&&void 0!==a&&a,contextualErrorMap:null==t?void 0:t.errorMap},path:(null==t?void 0:t.path)||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:n(e)},s=this._parseSync({data:e,path:r.path,parent:r});return j(r,s)}async parseAsync(e,t){const a=await this.safeParseAsync(e,t);if(a.success)return a.data;throw a.error}async safeParseAsync(e,t){const a={common:{issues:[],contextualErrorMap:null==t?void 0:t.errorMap,async:!0},path:(null==t?void 0:t.path)||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:n(e)},r=this._parse({data:e,path:a.path,parent:a}),s=await(b(r)?r:Promise.resolve(r));return j(a,s)}refine(e,t){const a=e=>"string"==typeof t||void 0===t?{message:t}:"function"==typeof t?t(e):t;return this._refinement((t,r)=>{const s=e(t),n=()=>r.addIssue({code:i.custom,...a(t)});return"undefined"!=typeof Promise&&s instanceof Promise?s.then(e=>!!e||(n(),!1)):!!s||(n(),!1)})}refinement(e,t){return this._refinement((a,r)=>!!e(a)||(r.addIssue("function"==typeof t?t(a,r):t),!1))}_refinement(e){return new Ze({schema:this,typeName:Ae.ZodEffects,effect:{type:"refinement",refinement:e}})}superRefine(e){return this._refinement(e)}optional(){return Ee.create(this,this._def)}nullable(){return je.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return ie.create(this,this._def)}promise(){return Te.create(this,this._def)}or(e){return ue.create([this,e],this._def)}and(e){return he.create(this,e,this._def)}transform(e){return new Ze({...O(this._def),schema:this,typeName:Ae.ZodEffects,effect:{type:"transform",transform:e}})}default(e){const t="function"==typeof e?e:()=>e;return new Oe({...O(this._def),innerType:this,defaultValue:t,typeName:Ae.ZodDefault})}brand(){return new Ie({typeName:Ae.ZodBranded,type:this,...O(this._def)})}catch(e){const t="function"==typeof e?e:()=>e;return new Ce({...O(this._def),innerType:this,catchValue:t,typeName:Ae.ZodCatch})}describe(e){return new(0,this.constructor)({...this._def,description:e})}pipe(e){return Re.create(this,e)}readonly(){return $e.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}}const S=/^c[^\s-]{8,}$/i,N=/^[0-9a-z]+$/,I=/^[0-9A-HJKMNP-TV-Z]{26}$/,R=/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i,$=/^[a-z0-9_-]{21}$/i,P=/^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/,M=/^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i;let A;const K=/^(?:(?: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])$/,L=/^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/,D=/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,V="((\\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])))",U=new RegExp(`^${V}$`);function z(e){let t="([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d";return e.precision?t=`${t}\\.\\d{${e.precision}}`:null==e.precision&&(t=`${t}(\\.\\d+)?`),t}function B(e){return new RegExp(`^${z(e)}$`)}function q(e){let t=`${V}T${z(e)}`;const a=[];return a.push(e.local?"Z?":"Z"),e.offset&&a.push("([+-]\\d{2}:?\\d{2})"),t=`${t}(${a.join("|")})`,new RegExp(`^${t}$`)}function F(e,t){return!("v4"!==t&&t||!K.test(e))||!("v6"!==t&&t||!L.test(e))}class W extends C{_parse(t){this._def.coerce&&(t.data=String(t.data));if(this._getType(t)!==s.string){const e=this._getOrReturnCtx(t);return p(e,{code:i.invalid_type,expected:s.string,received:e.parsedType}),m}const a=new h;let r;for(const s of this._def.checks)if("min"===s.kind)t.data.length<s.value&&(r=this._getOrReturnCtx(t,r),p(r,{code:i.too_small,minimum:s.value,type:"string",inclusive:!0,exact:!1,message:s.message}),a.dirty());else if("max"===s.kind)t.data.length>s.value&&(r=this._getOrReturnCtx(t,r),p(r,{code:i.too_big,maximum:s.value,type:"string",inclusive:!0,exact:!1,message:s.message}),a.dirty());else if("length"===s.kind){const e=t.data.length>s.value,n=t.data.length<s.value;(e||n)&&(r=this._getOrReturnCtx(t,r),e?p(r,{code:i.too_big,maximum:s.value,type:"string",inclusive:!0,exact:!0,message:s.message}):n&&p(r,{code:i.too_small,minimum:s.value,type:"string",inclusive:!0,exact:!0,message:s.message}),a.dirty())}else if("email"===s.kind)M.test(t.data)||(r=this._getOrReturnCtx(t,r),p(r,{validation:"email",code:i.invalid_string,message:s.message}),a.dirty());else if("emoji"===s.kind)A||(A=new RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$","u")),A.test(t.data)||(r=this._getOrReturnCtx(t,r),p(r,{validation:"emoji",code:i.invalid_string,message:s.message}),a.dirty());else if("uuid"===s.kind)R.test(t.data)||(r=this._getOrReturnCtx(t,r),p(r,{validation:"uuid",code:i.invalid_string,message:s.message}),a.dirty());else if("nanoid"===s.kind)$.test(t.data)||(r=this._getOrReturnCtx(t,r),p(r,{validation:"nanoid",code:i.invalid_string,message:s.message}),a.dirty());else if("cuid"===s.kind)S.test(t.data)||(r=this._getOrReturnCtx(t,r),p(r,{validation:"cuid",code:i.invalid_string,message:s.message}),a.dirty());else if("cuid2"===s.kind)N.test(t.data)||(r=this._getOrReturnCtx(t,r),p(r,{validation:"cuid2",code:i.invalid_string,message:s.message}),a.dirty());else if("ulid"===s.kind)I.test(t.data)||(r=this._getOrReturnCtx(t,r),p(r,{validation:"ulid",code:i.invalid_string,message:s.message}),a.dirty());else if("url"===s.kind)try{new URL(t.data)}catch(e){r=this._getOrReturnCtx(t,r),p(r,{validation:"url",code:i.invalid_string,message:s.message}),a.dirty()}else if("regex"===s.kind){s.regex.lastIndex=0;s.regex.test(t.data)||(r=this._getOrReturnCtx(t,r),p(r,{validation:"regex",code:i.invalid_string,message:s.message}),a.dirty())}else if("trim"===s.kind)t.data=t.data.trim();else if("includes"===s.kind)t.data.includes(s.value,s.position)||(r=this._getOrReturnCtx(t,r),p(r,{code:i.invalid_string,validation:{includes:s.value,position:s.position},message:s.message}),a.dirty());else if("toLowerCase"===s.kind)t.data=t.data.toLowerCase();else if("toUpperCase"===s.kind)t.data=t.data.toUpperCase();else if("startsWith"===s.kind)t.data.startsWith(s.value)||(r=this._getOrReturnCtx(t,r),p(r,{code:i.invalid_string,validation:{startsWith:s.value},message:s.message}),a.dirty());else if("endsWith"===s.kind)t.data.endsWith(s.value)||(r=this._getOrReturnCtx(t,r),p(r,{code:i.invalid_string,validation:{endsWith:s.value},message:s.message}),a.dirty());else if("datetime"===s.kind){q(s).test(t.data)||(r=this._getOrReturnCtx(t,r),p(r,{code:i.invalid_string,validation:"datetime",message:s.message}),a.dirty())}else if("date"===s.kind){U.test(t.data)||(r=this._getOrReturnCtx(t,r),p(r,{code:i.invalid_string,validation:"date",message:s.message}),a.dirty())}else if("time"===s.kind){B(s).test(t.data)||(r=this._getOrReturnCtx(t,r),p(r,{code:i.invalid_string,validation:"time",message:s.message}),a.dirty())}else"duration"===s.kind?P.test(t.data)||(r=this._getOrReturnCtx(t,r),p(r,{validation:"duration",code:i.invalid_string,message:s.message}),a.dirty()):"ip"===s.kind?F(t.data,s.version)||(r=this._getOrReturnCtx(t,r),p(r,{validation:"ip",code:i.invalid_string,message:s.message}),a.dirty()):"base64"===s.kind?D.test(t.data)||(r=this._getOrReturnCtx(t,r),p(r,{validation:"base64",code:i.invalid_string,message:s.message}),a.dirty()):e.assertNever(s);return{status:a.value,value:t.data}}_regex(e,t,a){return this.refinement(t=>e.test(t),{validation:t,code:i.invalid_string,...w.errToObj(a)})}_addCheck(e){return new W({...this._def,checks:[...this._def.checks,e]})}email(e){return this._addCheck({kind:"email",...w.errToObj(e)})}url(e){return this._addCheck({kind:"url",...w.errToObj(e)})}emoji(e){return this._addCheck({kind:"emoji",...w.errToObj(e)})}uuid(e){return this._addCheck({kind:"uuid",...w.errToObj(e)})}nanoid(e){return this._addCheck({kind:"nanoid",...w.errToObj(e)})}cuid(e){return this._addCheck({kind:"cuid",...w.errToObj(e)})}cuid2(e){return this._addCheck({kind:"cuid2",...w.errToObj(e)})}ulid(e){return this._addCheck({kind:"ulid",...w.errToObj(e)})}base64(e){return this._addCheck({kind:"base64",...w.errToObj(e)})}ip(e){return this._addCheck({kind:"ip",...w.errToObj(e)})}datetime(e){var t,a;return"string"==typeof e?this._addCheck({kind:"datetime",precision:null,offset:!1,local:!1,message:e}):this._addCheck({kind:"datetime",precision:void 0===(null==e?void 0:e.precision)?null:null==e?void 0:e.precision,offset:null!==(t=null==e?void 0:e.offset)&&void 0!==t&&t,local:null!==(a=null==e?void 0:e.local)&&void 0!==a&&a,...w.errToObj(null==e?void 0:e.message)})}date(e){return this._addCheck({kind:"date",message:e})}time(e){return"string"==typeof e?this._addCheck({kind:"time",precision:null,message:e}):this._addCheck({kind:"time",precision:void 0===(null==e?void 0:e.precision)?null:null==e?void 0:e.precision,...w.errToObj(null==e?void 0:e.message)})}duration(e){return this._addCheck({kind:"duration",...w.errToObj(e)})}regex(e,t){return this._addCheck({kind:"regex",regex:e,...w.errToObj(t)})}includes(e,t){return this._addCheck({kind:"includes",value:e,position:null==t?void 0:t.position,...w.errToObj(null==t?void 0:t.message)})}startsWith(e,t){return this._addCheck({kind:"startsWith",value:e,...w.errToObj(t)})}endsWith(e,t){return this._addCheck({kind:"endsWith",value:e,...w.errToObj(t)})}min(e,t){return this._addCheck({kind:"min",value:e,...w.errToObj(t)})}max(e,t){return this._addCheck({kind:"max",value:e,...w.errToObj(t)})}length(e,t){return this._addCheck({kind:"length",value:e,...w.errToObj(t)})}nonempty(e){return this.min(1,w.errToObj(e))}trim(){return new W({...this._def,checks:[...this._def.checks,{kind:"trim"}]})}toLowerCase(){return new W({...this._def,checks:[...this._def.checks,{kind:"toLowerCase"}]})}toUpperCase(){return new W({...this._def,checks:[...this._def.checks,{kind:"toUpperCase"}]})}get isDatetime(){return!!this._def.checks.find(e=>"datetime"===e.kind)}get isDate(){return!!this._def.checks.find(e=>"date"===e.kind)}get isTime(){return!!this._def.checks.find(e=>"time"===e.kind)}get isDuration(){return!!this._def.checks.find(e=>"duration"===e.kind)}get isEmail(){return!!this._def.checks.find(e=>"email"===e.kind)}get isURL(){return!!this._def.checks.find(e=>"url"===e.kind)}get isEmoji(){return!!this._def.checks.find(e=>"emoji"===e.kind)}get isUUID(){return!!this._def.checks.find(e=>"uuid"===e.kind)}get isNANOID(){return!!this._def.checks.find(e=>"nanoid"===e.kind)}get isCUID(){return!!this._def.checks.find(e=>"cuid"===e.kind)}get isCUID2(){return!!this._def.checks.find(e=>"cuid2"===e.kind)}get isULID(){return!!this._def.checks.find(e=>"ulid"===e.kind)}get isIP(){return!!this._def.checks.find(e=>"ip"===e.kind)}get isBase64(){return!!this._def.checks.find(e=>"base64"===e.kind)}get minLength(){let e=null;for(const t of this._def.checks)"min"===t.kind&&(null===e||t.value>e)&&(e=t.value);return e}get maxLength(){let e=null;for(const t of this._def.checks)"max"===t.kind&&(null===e||t.value<e)&&(e=t.value);return e}}function H(e,t){const a=(e.toString().split(".")[1]||"").length,r=(t.toString().split(".")[1]||"").length,s=a>r?a:r;return parseInt(e.toFixed(s).replace(".",""))%parseInt(t.toFixed(s).replace(".",""))/Math.pow(10,s)}W.create=e=>{var t;return new W({checks:[],typeName:Ae.ZodString,coerce:null!==(t=null==e?void 0:e.coerce)&&void 0!==t&&t,...O(e)})};class G extends C{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(t){this._def.coerce&&(t.data=Number(t.data));if(this._getType(t)!==s.number){const e=this._getOrReturnCtx(t);return p(e,{code:i.invalid_type,expected:s.number,received:e.parsedType}),m}let a;const r=new h;for(const s of this._def.checks)if("int"===s.kind)e.isInteger(t.data)||(a=this._getOrReturnCtx(t,a),p(a,{code:i.invalid_type,expected:"integer",received:"float",message:s.message}),r.dirty());else if("min"===s.kind){(s.inclusive?t.data<s.value:t.data<=s.value)&&(a=this._getOrReturnCtx(t,a),p(a,{code:i.too_small,minimum:s.value,type:"number",inclusive:s.inclusive,exact:!1,message:s.message}),r.dirty())}else if("max"===s.kind){(s.inclusive?t.data>s.value:t.data>=s.value)&&(a=this._getOrReturnCtx(t,a),p(a,{code:i.too_big,maximum:s.value,type:"number",inclusive:s.inclusive,exact:!1,message:s.message}),r.dirty())}else"multipleOf"===s.kind?0!==H(t.data,s.value)&&(a=this._getOrReturnCtx(t,a),p(a,{code:i.not_multiple_of,multipleOf:s.value,message:s.message}),r.dirty()):"finite"===s.kind?Number.isFinite(t.data)||(a=this._getOrReturnCtx(t,a),p(a,{code:i.not_finite,message:s.message}),r.dirty()):e.assertNever(s);return{status:r.value,value:t.data}}gte(e,t){return this.setLimit("min",e,!0,w.toString(t))}gt(e,t){return this.setLimit("min",e,!1,w.toString(t))}lte(e,t){return this.setLimit("max",e,!0,w.toString(t))}lt(e,t){return this.setLimit("max",e,!1,w.toString(t))}setLimit(e,t,a,r){return new G({...this._def,checks:[...this._def.checks,{kind:e,value:t,inclusive:a,message:w.toString(r)}]})}_addCheck(e){return new G({...this._def,checks:[...this._def.checks,e]})}int(e){return this._addCheck({kind:"int",message:w.toString(e)})}positive(e){return this._addCheck({kind:"min",value:0,inclusive:!1,message:w.toString(e)})}negative(e){return this._addCheck({kind:"max",value:0,inclusive:!1,message:w.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:0,inclusive:!0,message:w.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:0,inclusive:!0,message:w.toString(e)})}multipleOf(e,t){return this._addCheck({kind:"multipleOf",value:e,message:w.toString(t)})}finite(e){return this._addCheck({kind:"finite",message:w.toString(e)})}safe(e){return this._addCheck({kind:"min",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:w.toString(e)})._addCheck({kind:"max",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:w.toString(e)})}get minValue(){let e=null;for(const t of this._def.checks)"min"===t.kind&&(null===e||t.value>e)&&(e=t.value);return e}get maxValue(){let e=null;for(const t of this._def.checks)"max"===t.kind&&(null===e||t.value<e)&&(e=t.value);return e}get isInt(){return!!this._def.checks.find(t=>"int"===t.kind||"multipleOf"===t.kind&&e.isInteger(t.value))}get isFinite(){let e=null,t=null;for(const a of this._def.checks){if("finite"===a.kind||"int"===a.kind||"multipleOf"===a.kind)return!0;"min"===a.kind?(null===t||a.value>t)&&(t=a.value):"max"===a.kind&&(null===e||a.value<e)&&(e=a.value)}return Number.isFinite(t)&&Number.isFinite(e)}}G.create=e=>new G({checks:[],typeName:Ae.ZodNumber,coerce:(null==e?void 0:e.coerce)||!1,...O(e)});class J extends C{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(t){this._def.coerce&&(t.data=BigInt(t.data));if(this._getType(t)!==s.bigint){const e=this._getOrReturnCtx(t);return p(e,{code:i.invalid_type,expected:s.bigint,received:e.parsedType}),m}let a;const r=new h;for(const s of this._def.checks)if("min"===s.kind){(s.inclusive?t.data<s.value:t.data<=s.value)&&(a=this._getOrReturnCtx(t,a),p(a,{code:i.too_small,type:"bigint",minimum:s.value,inclusive:s.inclusive,message:s.message}),r.dirty())}else if("max"===s.kind){(s.inclusive?t.data>s.value:t.data>=s.value)&&(a=this._getOrReturnCtx(t,a),p(a,{code:i.too_big,type:"bigint",maximum:s.value,inclusive:s.inclusive,message:s.message}),r.dirty())}else"multipleOf"===s.kind?t.data%s.value!==BigInt(0)&&(a=this._getOrReturnCtx(t,a),p(a,{code:i.not_multiple_of,multipleOf:s.value,message:s.message}),r.dirty()):e.assertNever(s);return{status:r.value,value:t.data}}gte(e,t){return this.setLimit("min",e,!0,w.toString(t))}gt(e,t){return this.setLimit("min",e,!1,w.toString(t))}lte(e,t){return this.setLimit("max",e,!0,w.toString(t))}lt(e,t){return this.setLimit("max",e,!1,w.toString(t))}setLimit(e,t,a,r){return new J({...this._def,checks:[...this._def.checks,{kind:e,value:t,inclusive:a,message:w.toString(r)}]})}_addCheck(e){return new J({...this._def,checks:[...this._def.checks,e]})}positive(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!1,message:w.toString(e)})}negative(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!1,message:w.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!0,message:w.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!0,message:w.toString(e)})}multipleOf(e,t){return this._addCheck({kind:"multipleOf",value:e,message:w.toString(t)})}get minValue(){let e=null;for(const t of this._def.checks)"min"===t.kind&&(null===e||t.value>e)&&(e=t.value);return e}get maxValue(){let e=null;for(const t of this._def.checks)"max"===t.kind&&(null===e||t.value<e)&&(e=t.value);return e}}J.create=e=>{var t;return new J({checks:[],typeName:Ae.ZodBigInt,coerce:null!==(t=null==e?void 0:e.coerce)&&void 0!==t&&t,...O(e)})};class Y extends C{_parse(e){this._def.coerce&&(e.data=Boolean(e.data));if(this._getType(e)!==s.boolean){const t=this._getOrReturnCtx(e);return p(t,{code:i.invalid_type,expected:s.boolean,received:t.parsedType}),m}return y(e.data)}}Y.create=e=>new Y({typeName:Ae.ZodBoolean,coerce:(null==e?void 0:e.coerce)||!1,...O(e)});class X extends C{_parse(t){this._def.coerce&&(t.data=new Date(t.data));if(this._getType(t)!==s.date){const e=this._getOrReturnCtx(t);return p(e,{code:i.invalid_type,expected:s.date,received:e.parsedType}),m}if(isNaN(t.data.getTime())){return p(this._getOrReturnCtx(t),{code:i.invalid_date}),m}const a=new h;let r;for(const s of this._def.checks)"min"===s.kind?t.data.getTime()<s.value&&(r=this._getOrReturnCtx(t,r),p(r,{code:i.too_small,message:s.message,inclusive:!0,exact:!1,minimum:s.value,type:"date"}),a.dirty()):"max"===s.kind?t.data.getTime()>s.value&&(r=this._getOrReturnCtx(t,r),p(r,{code:i.too_big,message:s.message,inclusive:!0,exact:!1,maximum:s.value,type:"date"}),a.dirty()):e.assertNever(s);return{status:a.value,value:new Date(t.data.getTime())}}_addCheck(e){return new X({...this._def,checks:[...this._def.checks,e]})}min(e,t){return this._addCheck({kind:"min",value:e.getTime(),message:w.toString(t)})}max(e,t){return this._addCheck({kind:"max",value:e.getTime(),message:w.toString(t)})}get minDate(){let e=null;for(const t of this._def.checks)"min"===t.kind&&(null===e||t.value>e)&&(e=t.value);return null!=e?new Date(e):null}get maxDate(){let e=null;for(const t of this._def.checks)"max"===t.kind&&(null===e||t.value<e)&&(e=t.value);return null!=e?new Date(e):null}}X.create=e=>new X({checks:[],coerce:(null==e?void 0:e.coerce)||!1,typeName:Ae.ZodDate,...O(e)});class Q extends C{_parse(e){if(this._getType(e)!==s.symbol){const t=this._getOrReturnCtx(e);return p(t,{code:i.invalid_type,expected:s.symbol,received:t.parsedType}),m}return y(e.data)}}Q.create=e=>new Q({typeName:Ae.ZodSymbol,...O(e)});class ee extends C{_parse(e){if(this._getType(e)!==s.undefined){const t=this._getOrReturnCtx(e);return p(t,{code:i.invalid_type,expected:s.undefined,received:t.parsedType}),m}return y(e.data)}}ee.create=e=>new ee({typeName:Ae.ZodUndefined,...O(e)});class te extends C{_parse(e){if(this._getType(e)!==s.null){const t=this._getOrReturnCtx(e);return p(t,{code:i.invalid_type,expected:s.null,received:t.parsedType}),m}return y(e.data)}}te.create=e=>new te({typeName:Ae.ZodNull,...O(e)});class ae extends C{constructor(){super(...arguments),this._any=!0}_parse(e){return y(e.data)}}ae.create=e=>new ae({typeName:Ae.ZodAny,...O(e)});class re extends C{constructor(){super(...arguments),this._unknown=!0}_parse(e){return y(e.data)}}re.create=e=>new re({typeName:Ae.ZodUnknown,...O(e)});class se extends C{_parse(e){const t=this._getOrReturnCtx(e);return p(t,{code:i.invalid_type,expected:s.never,received:t.parsedType}),m}}se.create=e=>new se({typeName:Ae.ZodNever,...O(e)});class ne extends C{_parse(e){if(this._getType(e)!==s.undefined){const t=this._getOrReturnCtx(e);return p(t,{code:i.invalid_type,expected:s.void,received:t.parsedType}),m}return y(e.data)}}ne.create=e=>new ne({typeName:Ae.ZodVoid,...O(e)});class ie extends C{_parse(e){const{ctx:t,status:a}=this._processInputParams(e),r=this._def;if(t.parsedType!==s.array)return p(t,{code:i.invalid_type,expected:s.array,received:t.parsedType}),m;if(null!==r.exactLength){const e=t.data.length>r.exactLength.value,s=t.data.length<r.exactLength.value;(e||s)&&(p(t,{code:e?i.too_big:i.too_small,minimum:s?r.exactLength.value:void 0,maximum:e?r.exactLength.value:void 0,type:"array",inclusive:!0,exact:!0,message:r.exactLength.message}),a.dirty())}if(null!==r.minLength&&t.data.length<r.minLength.value&&(p(t,{code:i.too_small,minimum:r.minLength.value,type:"array",inclusive:!0,exact:!1,message:r.minLength.message}),a.dirty()),null!==r.maxLength&&t.data.length>r.maxLength.value&&(p(t,{code:i.too_big,maximum:r.maxLength.value,type:"array",inclusive:!0,exact:!1,message:r.maxLength.message}),a.dirty()),t.common.async)return Promise.all([...t.data].map((e,a)=>r.type._parseAsync(new E(t,e,t.path,a)))).then(e=>h.mergeArray(a,e));const n=[...t.data].map((e,a)=>r.type._parseSync(new E(t,e,t.path,a)));return h.mergeArray(a,n)}get element(){return this._def.type}min(e,t){return new ie({...this._def,minLength:{value:e,message:w.toString(t)}})}max(e,t){return new ie({...this._def,maxLength:{value:e,message:w.toString(t)}})}length(e,t){return new ie({...this._def,exactLength:{value:e,message:w.toString(t)}})}nonempty(e){return this.min(1,e)}}function oe(e){if(e instanceof de){const t={};for(const a in e.shape){const r=e.shape[a];t[a]=Ee.create(oe(r))}return new de({...e._def,shape:()=>t})}return e instanceof ie?new ie({...e._def,type:oe(e.element)}):e instanceof Ee?Ee.create(oe(e.unwrap())):e instanceof je?je.create(oe(e.unwrap())):e instanceof me?me.create(e.items.map(e=>oe(e))):e}ie.create=(e,t)=>new ie({type:e,minLength:null,maxLength:null,exactLength:null,typeName:Ae.ZodArray,...O(t)});class de extends C{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(null!==this._cached)return this._cached;const t=this._def.shape(),a=e.objectKeys(t);return this._cached={shape:t,keys:a}}_parse(e){if(this._getType(e)!==s.object){const t=this._getOrReturnCtx(e);return p(t,{code:i.invalid_type,expected:s.object,received:t.parsedType}),m}const{status:t,ctx:a}=this._processInputParams(e),{shape:r,keys:n}=this._getCached(),o=[];if(!(this._def.catchall instanceof se&&"strip"===this._def.unknownKeys))for(const e in a.data)n.includes(e)||o.push(e);const d=[];for(const e of n){const t=r[e],s=a.data[e];d.push({key:{status:"valid",value:e},value:t._parse(new E(a,s,a.path,e)),alwaysSet:e in a.data})}if(this._def.catchall instanceof se){const e=this._def.unknownKeys;if("passthrough"===e)for(const e of o)d.push({key:{status:"valid",value:e},value:{status:"valid",value:a.data[e]}});else if("strict"===e)o.length>0&&(p(a,{code:i.unrecognized_keys,keys:o}),t.dirty());else if("strip"!==e)throw new Error("Internal ZodObject error: invalid unknownKeys value.")}else{const e=this._def.catchall;for(const t of o){const r=a.data[t];d.push({key:{status:"valid",value:t},value:e._parse(new E(a,r,a.path,t)),alwaysSet:t in a.data})}}return a.common.async?Promise.resolve().then(async()=>{const e=[];for(const t of d){const a=await t.key,r=await t.value;e.push({key:a,value:r,alwaysSet:t.alwaysSet})}return e}).then(e=>h.mergeObjectSync(t,e)):h.mergeObjectSync(t,d)}get shape(){return this._def.shape()}strict(e){return w.errToObj,new de({...this._def,unknownKeys:"strict",...void 0!==e?{errorMap:(t,a)=>{var r,s,n,i;const o=null!==(n=null===(s=(r=this._def).errorMap)||void 0===s?void 0:s.call(r,t,a).message)&&void 0!==n?n:a.defaultError;return"unrecognized_keys"===t.code?{message:null!==(i=w.errToObj(e).message)&&void 0!==i?i:o}:{message:o}}}:{}})}strip(){return new de({...this._def,unknownKeys:"strip"})}passthrough(){return new de({...this._def,unknownKeys:"passthrough"})}extend(e){return new de({...this._def,shape:()=>({...this._def.shape(),...e})})}merge(e){return new de({unknownKeys:e._def.unknownKeys,catchall:e._def.catchall,shape:()=>({...this._def.shape(),...e._def.shape()}),typeName:Ae.ZodObject})}setKey(e,t){return this.augment({[e]:t})}catchall(e){return new de({...this._def,catchall:e})}pick(t){const a={};return e.objectKeys(t).forEach(e=>{t[e]&&this.shape[e]&&(a[e]=this.shape[e])}),new de({...this._def,shape:()=>a})}omit(t){const a={};return e.objectKeys(this.shape).forEach(e=>{t[e]||(a[e]=this.shape[e])}),new de({...this._def,shape:()=>a})}deepPartial(){return oe(this)}partial(t){const a={};return e.objectKeys(this.shape).forEach(e=>{const r=this.shape[e];t&&!t[e]?a[e]=r:a[e]=r.optional()}),new de({...this._def,shape:()=>a})}required(t){const a={};return e.objectKeys(this.shape).forEach(e=>{if(t&&!t[e])a[e]=this.shape[e];else{let t=this.shape[e];for(;t instanceof Ee;)t=t._def.innerType;a[e]=t}}),new de({...this._def,shape:()=>a})}keyof(){return ke(e.objectKeys(this.shape))}}de.create=(e,t)=>new de({shape:()=>e,unknownKeys:"strip",catchall:se.create(),typeName:Ae.ZodObject,...O(t)}),de.strictCreate=(e,t)=>new de({shape:()=>e,unknownKeys:"strict",catchall:se.create(),typeName:Ae.ZodObject,...O(t)}),de.lazycreate=(e,t)=>new de({shape:e,unknownKeys:"strip",catchall:se.create(),typeName:Ae.ZodObject,...O(t)});class ue extends C{_parse(e){const{ctx:t}=this._processInputParams(e),a=this._def.options;if(t.common.async)return Promise.all(a.map(async e=>{const a={...t,common:{...t.common,issues:[]},parent:null};return{result:await e._parseAsync({data:t.data,path:t.path,parent:a}),ctx:a}})).then(function(e){for(const t of e)if("valid"===t.result.status)return t.result;for(const a of e)if("dirty"===a.result.status)return t.common.issues.push(...a.ctx.common.issues),a.result;const a=e.map(e=>new o(e.ctx.common.issues));return p(t,{code:i.invalid_union,unionErrors:a}),m});{let e;const r=[];for(const s of a){const a={...t,common:{...t.common,issues:[]},parent:null},n=s._parseSync({data:t.data,path:t.path,parent:a});if("valid"===n.status)return n;"dirty"!==n.status||e||(e={result:n,ctx:a}),a.common.issues.length&&r.push(a.common.issues)}if(e)return t.common.issues.push(...e.ctx.common.issues),e.result;const s=r.map(e=>new o(e));return p(t,{code:i.invalid_union,unionErrors:s}),m}}get options(){return this._def.options}}ue.create=(e,t)=>new ue({options:e,typeName:Ae.ZodUnion,...O(t)});const ce=t=>t instanceof _e?ce(t.schema):t instanceof Ze?ce(t.innerType()):t instanceof be?[t.value]:t instanceof xe?t.options:t instanceof we?e.objectValues(t.enum):t instanceof Oe?ce(t._def.innerType):t instanceof ee?[void 0]:t instanceof te?[null]:t instanceof Ee?[void 0,...ce(t.unwrap())]:t instanceof je?[null,...ce(t.unwrap())]:t instanceof Ie||t instanceof $e?ce(t.unwrap()):t instanceof Ce?ce(t._def.innerType):[];class le extends C{_parse(e){const{ctx:t}=this._processInputParams(e);if(t.parsedType!==s.object)return p(t,{code:i.invalid_type,expected:s.object,received:t.parsedType}),m;const a=this.discriminator,r=t.data[a],n=this.optionsMap.get(r);return n?t.common.async?n._parseAsync({data:t.data,path:t.path,parent:t}):n._parseSync({data:t.data,path:t.path,parent:t}):(p(t,{code:i.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[a]}),m)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(e,t,a){const r=new Map;for(const a of t){const t=ce(a.shape[e]);if(!t.length)throw new Error(`A discriminator value for key \`${e}\` could not be extracted from all schema options`);for(const s of t){if(r.has(s))throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(s)}`);r.set(s,a)}}return new le({typeName:Ae.ZodDiscriminatedUnion,discriminator:e,options:t,optionsMap:r,...O(a)})}}function pe(t,a){const r=n(t),i=n(a);if(t===a)return{valid:!0,data:t};if(r===s.object&&i===s.object){const r=e.objectKeys(a),s=e.objectKeys(t).filter(e=>-1!==r.indexOf(e)),n={...t,...a};for(const e of s){const r=pe(t[e],a[e]);if(!r.valid)return{valid:!1};n[e]=r.data}return{valid:!0,data:n}}if(r===s.array&&i===s.array){if(t.length!==a.length)return{valid:!1};const e=[];for(let r=0;r<t.length;r++){const s=pe(t[r],a[r]);if(!s.valid)return{valid:!1};e.push(s.data)}return{valid:!0,data:e}}return r===s.date&&i===s.date&&+t===+a?{valid:!0,data:t}:{valid:!1}}class he extends C{_parse(e){const{status:t,ctx:a}=this._processInputParams(e),r=(e,r)=>{if(v(e)||v(r))return m;const s=pe(e.value,r.value);return s.valid?((g(e)||g(r))&&t.dirty(),{status:t.value,value:s.data}):(p(a,{code:i.invalid_intersection_types}),m)};return a.common.async?Promise.all([this._def.left._parseAsync({data:a.data,path:a.path,parent:a}),this._def.right._parseAsync({data:a.data,path:a.path,parent:a})]).then(([e,t])=>r(e,t)):r(this._def.left._parseSync({data:a.data,path:a.path,parent:a}),this._def.right._parseSync({data:a.data,path:a.path,parent:a}))}}he.create=(e,t,a)=>new he({left:e,right:t,typeName:Ae.ZodIntersection,...O(a)});class me extends C{_parse(e){const{status:t,ctx:a}=this._processInputParams(e);if(a.parsedType!==s.array)return p(a,{code:i.invalid_type,expected:s.array,received:a.parsedType}),m;if(a.data.length<this._def.items.length)return p(a,{code:i.too_small,minimum:this._def.items.length,inclusive:!0,exact:!1,type:"array"}),m;!this._def.rest&&a.data.length>this._def.items.length&&(p(a,{code:i.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:"array"}),t.dirty());const r=[...a.data].map((e,t)=>{const r=this._def.items[t]||this._def.rest;return r?r._parse(new E(a,e,a.path,t)):null}).filter(e=>!!e);return a.common.async?Promise.all(r).then(e=>h.mergeArray(t,e)):h.mergeArray(t,r)}get items(){return this._def.items}rest(e){return new me({...this._def,rest:e})}}me.create=(e,t)=>{if(!Array.isArray(e))throw new Error("You must pass an array of schemas to z.tuple([ ... ])");return new me({items:e,typeName:Ae.ZodTuple,rest:null,...O(t)})};class fe extends C{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){const{status:t,ctx:a}=this._processInputParams(e);if(a.parsedType!==s.object)return p(a,{code:i.invalid_type,expected:s.object,received:a.parsedType}),m;const r=[],n=this._def.keyType,o=this._def.valueType;for(const e in a.data)r.push({key:n._parse(new E(a,e,a.path,e)),value:o._parse(new E(a,a.data[e],a.path,e)),alwaysSet:e in a.data});return a.common.async?h.mergeObjectAsync(t,r):h.mergeObjectSync(t,r)}get element(){return this._def.valueType}static create(e,t,a){return new fe(t instanceof C?{keyType:e,valueType:t,typeName:Ae.ZodRecord,...O(a)}:{keyType:W.create(),valueType:e,typeName:Ae.ZodRecord,...O(t)})}}class ye extends C{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){const{status:t,ctx:a}=this._processInputParams(e);if(a.parsedType!==s.map)return p(a,{code:i.invalid_type,expected:s.map,received:a.parsedType}),m;const r=this._def.keyType,n=this._def.valueType,o=[...a.data.entries()].map(([e,t],s)=>({key:r._parse(new E(a,e,a.path,[s,"key"])),value:n._parse(new E(a,t,a.path,[s,"value"]))}));if(a.common.async){const e=new Map;return Promise.resolve().then(async()=>{for(const a of o){const r=await a.key,s=await a.value;if("aborted"===r.status||"aborted"===s.status)return m;"dirty"!==r.status&&"dirty"!==s.status||t.dirty(),e.set(r.value,s.value)}return{status:t.value,value:e}})}{const e=new Map;for(const a of o){const r=a.key,s=a.value;if("aborted"===r.status||"aborted"===s.status)return m;"dirty"!==r.status&&"dirty"!==s.status||t.dirty(),e.set(r.value,s.value)}return{status:t.value,value:e}}}}ye.create=(e,t,a)=>new ye({valueType:t,keyType:e,typeName:Ae.ZodMap,...O(a)});class ve extends C{_parse(e){const{status:t,ctx:a}=this._processInputParams(e);if(a.parsedType!==s.set)return p(a,{code:i.invalid_type,expected:s.set,received:a.parsedType}),m;const r=this._def;null!==r.minSize&&a.data.size<r.minSize.value&&(p(a,{code:i.too_small,minimum:r.minSize.value,type:"set",inclusive:!0,exact:!1,message:r.minSize.message}),t.dirty()),null!==r.maxSize&&a.data.size>r.maxSize.value&&(p(a,{code:i.too_big,maximum:r.maxSize.value,type:"set",inclusive:!0,exact:!1,message:r.maxSize.message}),t.dirty());const n=this._def.valueType;function o(e){const a=new Set;for(const r of e){if("aborted"===r.status)return m;"dirty"===r.status&&t.dirty(),a.add(r.value)}return{status:t.value,value:a}}const d=[...a.data.values()].map((e,t)=>n._parse(new E(a,e,a.path,t)));return a.common.async?Promise.all(d).then(e=>o(e)):o(d)}min(e,t){return new ve({...this._def,minSize:{value:e,message:w.toString(t)}})}max(e,t){return new ve({...this._def,maxSize:{value:e,message:w.toString(t)}})}size(e,t){return this.min(e,t).max(e,t)}nonempty(e){return this.min(1,e)}}ve.create=(e,t)=>new ve({valueType:e,minSize:null,maxSize:null,typeName:Ae.ZodSet,...O(t)});class ge extends C{constructor(){super(...arguments),this.validate=this.implement}_parse(e){const{ctx:t}=this._processInputParams(e);if(t.parsedType!==s.function)return p(t,{code:i.invalid_type,expected:s.function,received:t.parsedType}),m;function a(e,a){return l({data:e,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,c(),d].filter(e=>!!e),issueData:{code:i.invalid_arguments,argumentsError:a}})}function r(e,a){return l({data:e,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,c(),d].filter(e=>!!e),issueData:{code:i.invalid_return_type,returnTypeError:a}})}const n={errorMap:t.common.contextualErrorMap},u=t.data;if(this._def.returns instanceof Te){const e=this;return y(async function(...t){const s=new o([]),i=await e._def.args.parseAsync(t,n).catch(e=>{throw s.addIssue(a(t,e)),s}),d=await Reflect.apply(u,this,i);return await e._def.returns._def.type.parseAsync(d,n).catch(e=>{throw s.addIssue(r(d,e)),s})})}{const e=this;return y(function(...t){const s=e._def.args.safeParse(t,n);if(!s.success)throw new o([a(t,s.error)]);const i=Reflect.apply(u,this,s.data),d=e._def.returns.safeParse(i,n);if(!d.success)throw new o([r(i,d.error)]);return d.data})}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...e){return new ge({...this._def,args:me.create(e).rest(re.create())})}returns(e){return new ge({...this._def,returns:e})}implement(e){return this.parse(e)}strictImplement(e){return this.parse(e)}static create(e,t,a){return new ge({args:e||me.create([]).rest(re.create()),returns:t||re.create(),typeName:Ae.ZodFunction,...O(a)})}}class _e extends C{get schema(){return this._def.getter()}_parse(e){const{ctx:t}=this._processInputParams(e);return this._def.getter()._parse({data:t.data,path:t.path,parent:t})}}_e.create=(e,t)=>new _e({getter:e,typeName:Ae.ZodLazy,...O(t)});class be extends C{_parse(e){if(e.data!==this._def.value){const t=this._getOrReturnCtx(e);return p(t,{received:t.data,code:i.invalid_literal,expected:this._def.value}),m}return{status:"valid",value:e.data}}get value(){return this._def.value}}function ke(e,t){return new xe({values:e,typeName:Ae.ZodEnum,...O(t)})}be.create=(e,t)=>new be({value:e,typeName:Ae.ZodLiteral,...O(t)});class xe extends C{constructor(){super(...arguments),T.set(this,void 0)}_parse(t){if("string"!=typeof t.data){const a=this._getOrReturnCtx(t),r=this._def.values;return p(a,{expected:e.joinValues(r),received:a.parsedType,code:i.invalid_type}),m}if(k(this,T,"f")||x(this,T,new Set(this._def.values),"f"),!k(this,T,"f").has(t.data)){const e=this._getOrReturnCtx(t),a=this._def.values;return p(e,{received:e.data,code:i.invalid_enum_value,options:a}),m}return y(t.data)}get options(){return this._def.values}get enum(){const e={};for(const t of this._def.values)e[t]=t;return e}get Values(){const e={};for(const t of this._def.values)e[t]=t;return e}get Enum(){const e={};for(const t of this._def.values)e[t]=t;return e}extract(e,t=this._def){return xe.create(e,{...this._def,...t})}exclude(e,t=this._def){return xe.create(this.options.filter(t=>!e.includes(t)),{...this._def,...t})}}T=new WeakMap,xe.create=ke;class we extends C{constructor(){super(...arguments),Z.set(this,void 0)}_parse(t){const a=e.getValidEnumValues(this._def.values),r=this._getOrReturnCtx(t);if(r.parsedType!==s.string&&r.parsedType!==s.number){const t=e.objectValues(a);return p(r,{expected:e.joinValues(t),received:r.parsedType,code:i.invalid_type}),m}if(k(this,Z,"f")||x(this,Z,new Set(e.getValidEnumValues(this._def.values)),"f"),!k(this,Z,"f").has(t.data)){const t=e.objectValues(a);return p(r,{received:r.data,code:i.invalid_enum_value,options:t}),m}return y(t.data)}get enum(){return this._def.values}}Z=new WeakMap,we.create=(e,t)=>new we({values:e,typeName:Ae.ZodNativeEnum,...O(t)});class Te extends C{unwrap(){return this._def.type}_parse(e){const{ctx:t}=this._processInputParams(e);if(t.parsedType!==s.promise&&!1===t.common.async)return p(t,{code:i.invalid_type,expected:s.promise,received:t.parsedType}),m;const a=t.parsedType===s.promise?t.data:Promise.resolve(t.data);return y(a.then(e=>this._def.type.parseAsync(e,{path:t.path,errorMap:t.common.contextualErrorMap})))}}Te.create=(e,t)=>new Te({type:e,typeName:Ae.ZodPromise,...O(t)});class Ze extends C{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===Ae.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(t){const{status:a,ctx:r}=this._processInputParams(t),s=this._def.effect||null,n={addIssue:e=>{p(r,e),e.fatal?a.abort():a.dirty()},get path(){return r.path}};if(n.addIssue=n.addIssue.bind(n),"preprocess"===s.type){const e=s.transform(r.data,n);if(r.common.async)return Promise.resolve(e).then(async e=>{if("aborted"===a.value)return m;const t=await this._def.schema._parseAsync({data:e,path:r.path,parent:r});return"aborted"===t.status?m:"dirty"===t.status||"dirty"===a.value?f(t.value):t});{if("aborted"===a.value)return m;const t=this._def.schema._parseSync({data:e,path:r.path,parent:r});return"aborted"===t.status?m:"dirty"===t.status||"dirty"===a.value?f(t.value):t}}if("refinement"===s.type){const e=e=>{const t=s.refinement(e,n);if(r.common.async)return Promise.resolve(t);if(t instanceof Promise)throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");return e};if(!1===r.common.async){const t=this._def.schema._parseSync({data:r.data,path:r.path,parent:r});return"aborted"===t.status?m:("dirty"===t.status&&a.dirty(),e(t.value),{status:a.value,value:t.value})}return this._def.schema._parseAsync({data:r.data,path:r.path,parent:r}).then(t=>"aborted"===t.status?m:("dirty"===t.status&&a.dirty(),e(t.value).then(()=>({status:a.value,value:t.value}))))}if("transform"===s.type){if(!1===r.common.async){const e=this._def.schema._parseSync({data:r.data,path:r.path,parent:r});if(!_(e))return e;const t=s.transform(e.value,n);if(t instanceof Promise)throw new Error("Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.");return{status:a.value,value:t}}return this._def.schema._parseAsync({data:r.data,path:r.path,parent:r}).then(e=>_(e)?Promise.resolve(s.transform(e.value,n)).then(e=>({status:a.value,value:e})):e)}e.assertNever(s)}}Ze.create=(e,t,a)=>new Ze({schema:e,typeName:Ae.ZodEffects,effect:t,...O(a)}),Ze.createWithPreprocess=(e,t,a)=>new Ze({schema:t,effect:{type:"preprocess",transform:e},typeName:Ae.ZodEffects,...O(a)});class Ee extends C{_parse(e){return this._getType(e)===s.undefined?y(void 0):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}}Ee.create=(e,t)=>new Ee({innerType:e,typeName:Ae.ZodOptional,...O(t)});class je extends C{_parse(e){return this._getType(e)===s.null?y(null):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}}je.create=(e,t)=>new je({innerType:e,typeName:Ae.ZodNullable,...O(t)});class Oe extends C{_parse(e){const{ctx:t}=this._processInputParams(e);let a=t.data;return t.parsedType===s.undefined&&(a=this._def.defaultValue()),this._def.innerType._parse({data:a,path:t.path,parent:t})}removeDefault(){return this._def.innerType}}Oe.create=(e,t)=>new Oe({innerType:e,typeName:Ae.ZodDefault,defaultValue:"function"==typeof t.default?t.default:()=>t.default,...O(t)});class Ce extends C{_parse(e){const{ctx:t}=this._processInputParams(e),a={...t,common:{...t.common,issues:[]}},r=this._def.innerType._parse({data:a.data,path:a.path,parent:{...a}});return b(r)?r.then(e=>({status:"valid",value:"valid"===e.status?e.value:this._def.catchValue({get error(){return new o(a.common.issues)},input:a.data})})):{status:"valid",value:"valid"===r.status?r.value:this._def.catchValue({get error(){return new o(a.common.issues)},input:a.data})}}removeCatch(){return this._def.innerType}}Ce.create=(e,t)=>new Ce({innerType:e,typeName:Ae.ZodCatch,catchValue:"function"==typeof t.catch?t.catch:()=>t.catch,...O(t)});class Se extends C{_parse(e){if(this._getType(e)!==s.nan){const t=this._getOrReturnCtx(e);return p(t,{code:i.invalid_type,expected:s.nan,received:t.parsedType}),m}return{status:"valid",value:e.data}}}Se.create=e=>new Se({typeName:Ae.ZodNaN,...O(e)});const Ne=Symbol("zod_brand");class Ie extends C{_parse(e){const{ctx:t}=this._processInputParams(e),a=t.data;return this._def.type._parse({data:a,path:t.path,parent:t})}unwrap(){return this._def.type}}class Re extends C{_parse(e){const{status:t,ctx:a}=this._processInputParams(e);if(a.common.async){return(async()=>{const e=await this._def.in._parseAsync({data:a.data,path:a.path,parent:a});return"aborted"===e.status?m:"dirty"===e.status?(t.dirty(),f(e.value)):this._def.out._parseAsync({data:e.value,path:a.path,parent:a})})()}{const e=this._def.in._parseSync({data:a.data,path:a.path,parent:a});return"aborted"===e.status?m:"dirty"===e.status?(t.dirty(),{status:"dirty",value:e.value}):this._def.out._parseSync({data:e.value,path:a.path,parent:a})}}static create(e,t){return new Re({in:e,out:t,typeName:Ae.ZodPipeline})}}class $e extends C{_parse(e){const t=this._def.innerType._parse(e),a=e=>(_(e)&&(e.value=Object.freeze(e.value)),e);return b(t)?t.then(e=>a(e)):a(t)}unwrap(){return this._def.innerType}}function Pe(e,t={},a){return e?ae.create().superRefine((r,s)=>{var n,i;if(!e(r)){const e="function"==typeof t?t(r):"string"==typeof t?{message:t}:t,o=null===(i=null!==(n=e.fatal)&&void 0!==n?n:a)||void 0===i||i,d="string"==typeof e?{message:e}:e;s.addIssue({code:"custom",...d,fatal:o})}}):ae.create()}$e.create=(e,t)=>new $e({innerType:e,typeName:Ae.ZodReadonly,...O(t)});const Me={object:de.lazycreate};var Ae;!function(e){e.ZodString="ZodString",e.ZodNumber="ZodNumber",e.ZodNaN="ZodNaN",e.ZodBigInt="ZodBigInt",e.ZodBoolean="ZodBoolean",e.ZodDate="ZodDate",e.ZodSymbol="ZodSymbol",e.ZodUndefined="ZodUndefined",e.ZodNull="ZodNull",e.ZodAny="ZodAny",e.ZodUnknown="ZodUnknown",e.ZodNever="ZodNever",e.ZodVoid="ZodVoid",e.ZodArray="ZodArray",e.ZodObject="ZodObject",e.ZodUnion="ZodUnion",e.ZodDiscriminatedUnion="ZodDiscriminatedUnion",e.ZodIntersection="ZodIntersection",e.ZodTuple="ZodTuple",e.ZodRecord="ZodRecord",e.ZodMap="ZodMap",e.ZodSet="ZodSet",e.ZodFunction="ZodFunction",e.ZodLazy="ZodLazy",e.ZodLiteral="ZodLiteral",e.ZodEnum="ZodEnum",e.ZodEffects="ZodEffects",e.ZodNativeEnum="ZodNativeEnum",e.ZodOptional="ZodOptional",e.ZodNullable="ZodNullable",e.ZodDefault="ZodDefault",e.ZodCatch="ZodCatch",e.ZodPromise="ZodPromise",e.ZodBranded="ZodBranded",e.ZodPipeline="ZodPipeline",e.ZodReadonly="ZodReadonly"}(Ae||(Ae={}));const Ke=W.create,Le=G.create,De=Se.create,Ve=J.create,Ue=Y.create,ze=X.create,Be=Q.create,qe=ee.create,Fe=te.create,We=ae.create,He=re.create,Ge=se.create,Je=ne.create,Ye=ie.create,Xe=de.create,Qe=de.strictCreate,et=ue.create,tt=le.create,at=he.create,rt=me.create,st=fe.create,nt=ye.create,it=ve.create,ot=ge.create,dt=_e.create,ut=be.create,ct=xe.create,lt=we.create,pt=Te.create,ht=Ze.create,mt=Ee.create,ft=je.create,yt=Ze.createWithPreprocess,vt=Re.create,gt={string:e=>W.create({...e,coerce:!0}),number:e=>G.create({...e,coerce:!0}),boolean:e=>Y.create({...e,coerce:!0}),bigint:e=>J.create({...e,coerce:!0}),date:e=>X.create({...e,coerce:!0})},_t=m;var bt=Object.freeze({__proto__:null,defaultErrorMap:d,setErrorMap:function(e){u=e},getErrorMap:c,makeIssue:l,EMPTY_PATH:[],addIssueToContext:p,ParseStatus:h,INVALID:m,DIRTY:f,OK:y,isAborted:v,isDirty:g,isValid:_,isAsync:b,get util(){return e},get objectUtil(){return t},ZodParsedType:s,getParsedType:n,ZodType:C,datetimeRegex:q,ZodString:W,ZodNumber:G,ZodBigInt:J,ZodBoolean:Y,ZodDate:X,ZodSymbol:Q,ZodUndefined:ee,ZodNull:te,ZodAny:ae,ZodUnknown:re,ZodNever:se,ZodVoid:ne,ZodArray:ie,ZodObject:de,ZodUnion:ue,ZodDiscriminatedUnion:le,ZodIntersection:he,ZodTuple:me,ZodRecord:fe,ZodMap:ye,ZodSet:ve,ZodFunction:ge,ZodLazy:_e,ZodLiteral:be,ZodEnum:xe,ZodNativeEnum:we,ZodPromise:Te,ZodEffects:Ze,ZodTransformer:Ze,ZodOptional:Ee,ZodNullable:je,ZodDefault:Oe,ZodCatch:Ce,ZodNaN:Se,BRAND:Ne,ZodBranded:Ie,ZodPipeline:Re,ZodReadonly:$e,custom:Pe,Schema:C,ZodSchema:C,late:Me,get ZodFirstPartyTypeKind(){return Ae},coerce:gt,any:We,array:Ye,bigint:Ve,boolean:Ue,date:ze,discriminatedUnion:tt,effect:ht,enum:ct,function:ot,instanceof:(e,t={message:`Input not instance of ${e.name}`})=>Pe(t=>t instanceof e,t),intersection:at,lazy:dt,literal:ut,map:nt,nan:De,nativeEnum:lt,never:Ge,null:Fe,nullable:ft,number:Le,object:Xe,oboolean:()=>Ue().optional(),onumber:()=>Le().optional(),optional:mt,ostring:()=>Ke().optional(),pipeline:vt,preprocess:yt,promise:pt,record:st,set:it,strictObject:Qe,string:Ke,symbol:Be,transformer:ht,tuple:rt,undefined:qe,union:et,unknown:He,void:Je,NEVER:_t,ZodIssueCode:i,quotelessJson:e=>JSON.stringify(e,null,2).replace(/"([^"]+)":/g,"$1:"),ZodError:o}),kt=["interface","display","layout","module","panel","theme"],xt=["hook","endpoint"],wt=["operation"],Tt="directus:extension",Zt=bt.object({app:bt.string(),api:bt.string()}),Et=bt.object({request:bt.optional(bt.object({urls:bt.array(bt.string()),methods:bt.array(bt.union([bt.literal("GET"),bt.literal("POST"),bt.literal("PATCH"),bt.literal("PUT"),bt.literal("DELETE")]))})),log:bt.optional(bt.object({})),sleep:bt.optional(bt.object({}))}),jt=bt.optional(bt.object({enabled:bt.boolean(),requestedScopes:Et})),Ot=bt.union([bt.object({type:bt.enum(xt),name:bt.string(),source:bt.string()}),bt.object({type:bt.enum(kt),name:bt.string(),source:bt.string()}),bt.object({type:bt.enum(wt),name:bt.string(),source:Zt})]),Ct=bt.object({host:bt.string(),hidden:bt.boolean().optional()}),St=bt.object({type:bt.enum(kt),path:bt.string(),source:bt.string()}),Nt=bt.object({type:bt.enum(xt),path:bt.string(),source:bt.string(),sandbox:jt}),It=bt.object({type:bt.enum(wt),path:Zt,source:Zt,sandbox:jt}),Rt=bt.object({type:bt.literal("bundle"),partial:bt.boolean().optional(),path:Zt,entries:bt.array(Ot)});bt.array(Ot);var $t=Ct.and(bt.union([St,Nt,It,Rt]));bt.object({name:bt.string(),version:bt.string(),type:bt.union([bt.literal("module"),bt.literal("commonjs")]).optional(),description:bt.string().optional(),icon:bt.string().optional(),dependencies:bt.record(bt.string()).optional(),devDependencies:bt.record(bt.string()).optional(),[Tt]:$t});var Pt,Mt=({init:e},{database:t,logger:a})=>{e("app.after",async()=>{a.info("[KeyManager] Initializing — checking directus_keys schema...");await t.schema.hasTable("directus_keys")?a.info("[KeyManager] directus_keys table already exists — skipping creation."):(a.info("[KeyManager] Creating directus_keys table..."),await t.schema.createTable("directus_keys",e=>{e.uuid("id").primary().defaultTo(t.raw("(lower(hex(randomblob(4))) || '-' || lower(hex(randomblob(2))) || '-4' || substr(lower(hex(randomblob(2))),2) || '-' || substr('89ab',abs(random()) % 4 + 1, 1) || substr(lower(hex(randomblob(2))),2) || '-' || lower(hex(randomblob(6))))")),e.string("name",255).notNullable().unique(),e.enum("provider",["database","file","env","external"]).notNullable().defaultTo("database"),e.text("value").nullable(),e.text("source").nullable(),e.text("description").nullable(),e.timestamp("date_created").defaultTo(t.fn.now()),e.timestamp("date_updated").defaultTo(t.fn.now())}),a.info("[KeyManager] directus_keys table created successfully."))})},At=new Uint8Array(16);function Kt(){if(!Pt&&!(Pt="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return Pt(At)}var Lt=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;for(var Dt=[],Vt=0;Vt<256;++Vt)Dt.push((Vt+256).toString(16).substr(1));function Ut(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,a=(Dt[e[t+0]]+Dt[e[t+1]]+Dt[e[t+2]]+Dt[e[t+3]]+"-"+Dt[e[t+4]]+Dt[e[t+5]]+"-"+Dt[e[t+6]]+Dt[e[t+7]]+"-"+Dt[e[t+8]]+Dt[e[t+9]]+"-"+Dt[e[t+10]]+Dt[e[t+11]]+Dt[e[t+12]]+Dt[e[t+13]]+Dt[e[t+14]]+Dt[e[t+15]]).toLowerCase();if(!function(e){return"string"==typeof e&&Lt.test(e)}(a))throw TypeError("Stringified UUID is invalid");return a}function zt(e,t,a){var r=(e=e||{}).random||(e.rng||Kt)();if(r[6]=15&r[6]|64,r[8]=63&r[8]|128,t){a=a||0;for(var s=0;s<16;++s)t[a+s]=r[s];return t}return Ut(r)}const Bt="aes-256-gcm";function qt(){const e=process.env.SECRET??"fallback-insecure-secret";return a.createHash("sha256").update(e).digest()}function Ft(e){const t=qt(),r=a.randomBytes(12),s=a.createCipheriv(Bt,t,r),n=Buffer.concat([s.update(e,"utf8"),s.final()]),i=s.getAuthTag();return Buffer.concat([r,i,n]).toString("base64")}async function Wt(e,t){const r=await t("directus_keys").where({name:e}).first();if(!r)throw new Error(`[KeyManager] Key "${e}" not found in database.`);if(!r.value)throw new Error(`[KeyManager] Key "${e}" has no stored value.`);return function(e){const t=qt(),r=Buffer.from(e,"base64"),s=r.subarray(0,12),n=r.subarray(12,28),i=r.subarray(28),o=a.createDecipheriv(Bt,t,s);return o.setAuthTag(n),Buffer.concat([o.update(i),o.final()]).toString("utf8")}(r.value)}async function Ht(e,t){const a=await t("directus_keys").where({name:e}).first();if(!a)throw new Error(`[KeyManager] Key "${e}" not found.`);switch(a.provider){case"database":return Wt(e,t);case"file":if(!a.source)throw new Error(`[KeyManager] Key "${e}" (file provider) has no source path.`);return async function(e){if(!e)throw new Error('[KeyManager] File provider requires a file path in the "source" field.');try{return(await r.readFile(e,"utf8")).trim()}catch(t){throw new Error(`[KeyManager] Failed to read key file at "${e}": ${t.message}`)}}(a.source);case"env":if(!a.source)throw new Error(`[KeyManager] Key "${e}" (env provider) has no env var name.`);return function(e){if(!e)throw new Error('[KeyManager] Env provider requires an environment variable name in the "source" field.');const t=process.env[e];if(void 0===t)throw new Error(`[KeyManager] Environment variable "${e}" is not set.`);return t}(a.source);case"external":if(!a.source)throw new Error(`[KeyManager] Key "${e}" (external provider) has no URL.`);return async function(e){if(!e)throw new Error('[KeyManager] External provider requires a URL in the "source" field.');const t=process.env.KM_EXTERNAL_TOKEN,a={Accept:"application/json, text/plain"};let r;t&&(a.Authorization=`Bearer ${t}`);try{r=await fetch(e,{headers:a})}catch(t){throw new Error(`[KeyManager] External provider HTTP request to "${e}" failed: ${t.message}`)}if(!r.ok)throw new Error(`[KeyManager] External provider returned HTTP ${r.status} for "${e}".`);if((r.headers.get("content-type")??"").includes("application/json")){const t=await r.json(),a=t?.value??t?.data?.value??t?.secret??t?.SecretString??null;if(null==a)throw new Error(`[KeyManager] External provider response from "${e}" has no recognizable value field.`);return String(a)}return(await r.text()).trim()}(a.source);default:throw new Error(`[KeyManager] Unknown provider "${a.provider}" for key "${e}".`)}}const Gt=[{name:"key-hook",config:Mt}],Jt=[{name:"key-endpoint",config:{id:"km",handler:(e,{database:t,logger:a})=>{e.use((e,t,a)=>{const r=e.accountability;if(!r||!0!==r.admin)return t.status(403).json({errors:[{message:"Forbidden: admin access required.",extensions:{code:"FORBIDDEN"}}]});a()}),e.get("/keys",async(e,r)=>{try{const e=await t("directus_keys").select("id","name","provider","source","description","date_created","date_updated");r.json({data:e})}catch(e){a.error("[KeyManager] GET /km/keys error:",e),r.status(500).json({errors:[{message:e.message}]})}}),e.post("/keys",async(e,r)=>{const{name:s,provider:n,value:i,source:o,description:d}=e.body??{};if(!s||!n)return r.status(400).json({errors:[{message:'"name" and "provider" are required.'}]});if("database"===n&&!i)return r.status(400).json({errors:[{message:'"value" is required for the database provider.'}]});if(["file","env","external"].includes(n)&&!o)return r.status(400).json({errors:[{message:'"source" is required for file/env/external providers.'}]});try{const e=zt(),a="database"===n?Ft(i):null;await t("directus_keys").insert({id:e,name:s,provider:n,value:a,source:"database"!==n?o:null,description:d??null}),r.status(201).json({data:{id:e,name:s,provider:n,description:d}})}catch(e){a.error("[KeyManager] POST /km/keys error:",e);const t=e.message?.includes("UNIQUE");r.status(t?409:500).json({errors:[{message:t?`Key "${s}" already exists.`:e.message}]})}}),e.patch("/keys/:id",async(e,r)=>{const{id:s}=e.params,{value:n,source:i,description:o,provider:d}=e.body??{};try{const e=await t("directus_keys").where({id:s}).first();if(!e)return r.status(404).json({errors:[{message:"Key not found."}]});const a={date_updated:new Date};void 0!==o&&(a.description=o),void 0!==d&&(a.provider=d);"database"===(d??e.provider)&&n?(a.value=Ft(n),a.source=null):void 0!==i&&(a.source=i,a.value=null),await t("directus_keys").where({id:s}).update(a),r.json({data:{id:s,...a}})}catch(e){a.error("[KeyManager] PATCH /km/keys/:id error:",e),r.status(500).json({errors:[{message:e.message}]})}}),e.delete("/keys/:id",async(e,r)=>{const{id:s}=e.params;try{if(!await t("directus_keys").where({id:s}).delete())return r.status(404).json({errors:[{message:"Key not found."}]});r.json({data:{id:s}})}catch(e){a.error("[KeyManager] DELETE /km/keys/:id error:",e),r.status(500).json({errors:[{message:e.message}]})}}),e.get("/retrieve/:name",async(e,r)=>{const{name:s}=e.params;try{const e=await Ht(s,t);r.json({data:{name:s,value:e}})}catch(e){a.error(`[KeyManager] GET /km/retrieve/${s} error:`,e);const t=e.message?.includes("not found");r.status(t?404:500).json({errors:[{message:e.message}]})}})}}}];exports.endpoints=Jt,exports.hooks=Gt,exports.operations=[];
package/dist/app.js ADDED
@@ -0,0 +1 @@
1
+ import{useApi as e,useStores as a,defineModule as n}from"@directus/extensions-sdk";import{defineComponent as l,ref as r,computed as t,watch as o,resolveComponent as d,resolveDirective as i,openBlock as s,createBlock as u,withCtx as v,withDirectives as c,createVNode as p,createElementVNode as f,createTextVNode as m,toDisplayString as b,createCommentVNode as g,createElementBlock as y,Fragment as x,normalizeClass as h,onMounted as k}from"vue";const _={class:"key-form"},w={class:"form-field"},E={class:"form-field"},V={key:1,class:"form-field"},S={class:"form-field"},C={class:"form-field"},K={class:"form-field"},A={class:"form-field"};var D=l({__name:"KeyForm",props:{keyData:{}},emits:["close","saved"],setup(a,{emit:n}){const l=a,k=n,D=e(),T=r(!1),U=r(null),P=r(!0);function q(){P.value=!1,setTimeout(()=>k("close"),200)}const z=t(()=>!!l.keyData),R=r({name:"",provider:"database",value:"",source:"",description:""});o(()=>l.keyData,e=>{R.value=e?{name:e.name,provider:e.provider,value:"",source:e.source??"",description:e.description??""}:{name:"",provider:"database",value:"",source:"",description:""}},{immediate:!0});const M=[{text:"🗄️ Database (encrypted)",value:"database"},{text:"🖥️ Environment Variable",value:"env"}],N={database:{icon:"storage",label:"Database (Encrypted)",description:"Stores the value encrypted with AES-256-GCM in the Directus database. Recommended for development only."},file:{icon:"folder",label:"File",description:"Reads the secret from a file on the server. Store the file outside your web root for security."},env:{icon:"terminal",label:"Environment Variable",description:"Reads from a server-side environment variable. The value never touches the database."},external:{icon:"cloud",label:"External (Vault / KMS)",description:"Fetches the secret via HTTP from an external key management service like HashiCorp Vault or AWS Secrets Manager."}},L=t(()=>N[R.value.provider]?.icon??"help"),F=t(()=>N[R.value.provider]?.label??""),I=t(()=>N[R.value.provider]?.description??"");async function j(){if(U.value=null,R.value.name.trim())if(R.value.provider)if("database"!==R.value.provider||R.value.value||z.value)if(!["file","env","external"].includes(R.value.provider)||R.value.source.trim()){T.value=!0;try{if(z.value&&l.keyData){const e={provider:R.value.provider,description:R.value.description};"database"===R.value.provider&&R.value.value?e.value=R.value.value:R.value.source&&(e.source=R.value.source),await D.patch(`/km/keys/${l.keyData.id}`,e)}else await D.post("/km/keys",{name:R.value.name.trim(),provider:R.value.provider,value:"database"===R.value.provider?R.value.value:void 0,source:"database"!==R.value.provider?R.value.source.trim():void 0,description:R.value.description.trim()||void 0});k("saved")}catch(e){U.value=e?.response?.data?.errors?.[0]?.message??e.message}finally{T.value=!1}}else U.value="Source/path is required for this provider.";else U.value="Secret value is required for the database provider.";else U.value="Provider is required.";else U.value="Name is required."}return(e,a)=>{const n=d("v-icon"),l=d("v-button"),r=d("v-notice"),t=d("v-input"),o=d("v-select"),k=d("v-textarea"),D=d("v-drawer"),N=i("tooltip");return s(),u(D,{"model-value":P.value,title:z.value?"Edit Key":"Add Key",icon:"key","onUpdate:modelValue":q,onCancel:q},{actions:v(()=>[c((s(),u(l,{rounded:"",icon:"",loading:T.value,onClick:j},{default:v(()=>[p(n,{name:"check"})]),_:1},8,["loading"])),[[N,"Save",void 0,{bottom:!0}]])]),default:v(()=>[f("div",_,[U.value?(s(),u(r,{key:0,type:"danger",class:"form-error"},{default:v(()=>[m(b(U.value),1)]),_:1})):g("v-if",!0),g(" Name "),f("div",w,[a[7]||(a[7]=f("label",{class:"form-label"},[m(" Name "),f("span",{class:"required"},"*"),f("span",{class:"hint"},"Unique identifier, e.g. STRIPE_SECRET_KEY")],-1)),p(t,{modelValue:R.value.name,"onUpdate:modelValue":a[0]||(a[0]=e=>R.value.name=e),disabled:z.value,placeholder:"MY_API_KEY","font-mono":""},null,8,["modelValue","disabled"])]),g(" Provider "),f("div",E,[a[8]||(a[8]=f("label",{class:"form-label"},[m(" Provider "),f("span",{class:"required"},"*"),f("span",{class:"hint"},"Where is this secret stored?")],-1)),p(o,{modelValue:R.value.provider,"onUpdate:modelValue":a[1]||(a[1]=e=>R.value.provider=e),items:M},null,8,["modelValue"])]),g(" Provider: database — show value input "),"database"===R.value.provider?(s(),y("div",V,[a[10]||(a[10]=f("label",{class:"form-label"},[m(" Secret Value "),f("span",{class:"required"},"*"),f("span",{class:"hint"},"Will be encrypted (AES-256-GCM) before storage.")],-1)),p(t,{modelValue:R.value.value,"onUpdate:modelValue":a[2]||(a[2]=e=>R.value.value=e),type:"password",placeholder:"Enter the secret value...","placeholder-color":"var(--foreground-subdued)"},null,8,["modelValue"]),p(r,{type:"warning",class:"field-notice"},{default:v(()=>[p(n,{name:"info","x-small":""}),a[9]||(a[9]=m(" Recommended for development only. Use file, env, or external for production. ",-1))]),_:1})])):"file"===R.value.provider?(s(),y(x,{key:2},[g(" Provider: file — show path input "),f("div",S,[a[11]||(a[11]=f("label",{class:"form-label"},[m(" File Path "),f("span",{class:"required"},"*"),f("span",{class:"hint"},"Absolute path on the server, outside the web root.")],-1)),p(t,{modelValue:R.value.source,"onUpdate:modelValue":a[3]||(a[3]=e=>R.value.source=e),placeholder:"/run/secrets/api_key.txt","font-mono":""},null,8,["modelValue"])])],2112)):"env"===R.value.provider?(s(),y(x,{key:3},[g(" Provider: env — show env var name input "),f("div",C,[a[12]||(a[12]=f("label",{class:"form-label"},[m(" Environment Variable Name "),f("span",{class:"required"},"*"),f("span",{class:"hint"},"The exact name of the environment variable on the server.")],-1)),p(t,{modelValue:R.value.source,"onUpdate:modelValue":a[4]||(a[4]=e=>R.value.source=e),placeholder:"STRIPE_SECRET_KEY","font-mono":""},null,8,["modelValue"])])],2112)):"external"===R.value.provider?(s(),y(x,{key:4},[g(" Provider: external — show URL input "),f("div",K,[a[16]||(a[16]=f("label",{class:"form-label"},[m(" External URL "),f("span",{class:"required"},"*"),f("span",{class:"hint"},"URL to fetch the secret from (Vault, AWS Secrets Manager, etc.)")],-1)),p(t,{modelValue:R.value.source,"onUpdate:modelValue":a[5]||(a[5]=e=>R.value.source=e),placeholder:"https://vault.example.com/v1/secret/data/my-key","font-mono":""},null,8,["modelValue"]),p(r,{type:"info",class:"field-notice"},{default:v(()=>[p(n,{name:"info","x-small":""}),a[13]||(a[13]=m(" Set ",-1)),a[14]||(a[14]=f("code",null,"KM_EXTERNAL_TOKEN",-1)),a[15]||(a[15]=m(" env var on the server to send a Bearer token. ",-1))]),_:1})])],2112)):g("v-if",!0),g(" Description "),f("div",A,[a[17]||(a[17]=f("label",{class:"form-label"},[m(" Description "),f("span",{class:"hint"},"Optional admin notes about this key.")],-1)),p(k,{modelValue:R.value.description,"onUpdate:modelValue":a[6]||(a[6]=e=>R.value.description=e),placeholder:"Used for Stripe payment processing...",rows:3},null,8,["modelValue"])]),g(" Provider InfoCard "),f("div",{class:h(["provider-infocard",`provider-${R.value.provider}`])},[p(n,{name:L.value},null,8,["name"]),f("div",null,[f("strong",null,b(F.value),1),f("p",null,b(I.value),1)])],2)])]),_:1},8,["model-value","title"])}}}),T=[],U=[];function P(e,a){if(e&&"undefined"!=typeof document){var n,l=!0===a.prepend?"prepend":"append",r=!0===a.singleTag,t="string"==typeof a.container?document.querySelector(a.container):document.getElementsByTagName("head")[0];if(r){var o=T.indexOf(t);-1===o&&(o=T.push(t)-1,U[o]={}),n=U[o]&&U[o][l]?U[o][l]:U[o][l]=d()}else n=d();65279===e.charCodeAt(0)&&(e=e.substring(1)),n.styleSheet?n.styleSheet.cssText+=e:n.appendChild(document.createTextNode(e))}function d(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),a.attributes)for(var n=Object.keys(a.attributes),r=0;r<n.length;r++)e.setAttribute(n[r],a.attributes[n[r]]);var o="prepend"===l?"afterbegin":"beforeend";return t.insertAdjacentElement(o,e),e}}P("\n.key-form[data-v-c7f698b3] {\n padding: 24px;\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n.form-error[data-v-c7f698b3] {\n margin: 0;\n}\n.form-field[data-v-c7f698b3] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.form-label[data-v-c7f698b3] {\n font-size: 14px;\n font-weight: 600;\n color: var(--foreground-normal);\n display: flex;\n align-items: baseline;\n gap: 6px;\n}\n.required[data-v-c7f698b3] {\n color: var(--danger);\n}\n.hint[data-v-c7f698b3] {\n font-size: 12px;\n font-weight: 400;\n color: var(--foreground-subdued);\n margin-left: auto;\n}\n.field-notice[data-v-c7f698b3] {\n margin-top: 4px;\n}\n.provider-infocard[data-v-c7f698b3] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 16px;\n border-radius: var(--border-radius);\n border: 1px solid var(--border-normal);\n}\n.provider-infocard p[data-v-c7f698b3] {\n margin: 4px 0 0;\n font-size: 13px;\n line-height: 1.5;\n color: var(--foreground-subdued);\n}\n.provider-infocard strong[data-v-c7f698b3] {\n font-size: 14px;\n color: var(--foreground-normal);\n}\n.provider-database[data-v-c7f698b3] { background: #e8f5e9; border-color: #a5d6a7;\n}\n.provider-file[data-v-c7f698b3] { background: #fff3e0; border-color: #ffcc80;\n}\n.provider-env[data-v-c7f698b3] { background: #e3f2fd; border-color: #90caf9;\n}\n.provider-external[data-v-c7f698b3] { background: #f3e5f5; border-color: #ce93d8;\n}\n",{});var q=(e,a)=>{const n=e.__vccOpts||e;for(const[e,l]of a)n[e]=l;return n},z=q(D,[["__scopeId","data-v-c7f698b3"],["__file","KeyForm.vue"]]);const R={class:"nav-info"},M={class:"key-manager-layout"},N={key:0,class:"loading-state"},L={class:"empty-state"},F={class:"key-table-wrapper"},I={key:0,class:"source-code"},j={key:1,class:"muted"},O={class:"row-actions"};var Y=l({__name:"KeyList",setup(n){const l=e(),{useNotificationsStore:t}=a(),o=t(),_=r([]),w=r(!0),E=r(null),V=r(!1),S=r(null),C=r(null),K=r(null),A=r(!1),D=[{text:"Name",value:"name",sortable:!0},{text:"Provider",value:"provider",sortable:!0},{text:"Source / Path",value:"source"},{text:"Description",value:"description"},{text:"Updated",value:"date_updated",sortable:!0},{text:"",value:"actions",align:"right",width:100}];async function T(){w.value=!0,E.value=null;try{const e=await l.get("/km/keys");_.value=e.data.data??[]}catch(e){E.value=e?.response?.data?.errors?.[0]?.message??e.message}finally{w.value=!1}}function U(){S.value=null,V.value=!0}function P(){C.value&&(S.value=C.value,C.value=null,V.value=!0)}function q(){V.value=!1,S.value=null}function Y(){q(),T(),o.add({title:"Key saved successfully",type:"success"})}async function W(){if(K.value){A.value=!0;try{await l.delete(`/km/keys/${K.value.id}`),o.add({title:"Key deleted",type:"success"}),K.value=null,T()}catch(e){o.add({title:"Delete failed",text:e?.response?.data?.errors?.[0]?.message??e.message,type:"error"})}finally{A.value=!1}}}function $(e){return{database:"Database",file:"File",env:"Env Var",external:"External"}[e]??e}return k(T),(e,a)=>{const n=d("v-icon"),l=d("v-button"),r=d("v-progress-circular"),t=d("v-notice"),o=d("v-text-overflow"),k=d("v-table"),T=d("v-card-title"),B=d("v-card-text"),G=d("v-card-actions"),H=d("v-card"),X=d("v-dialog"),J=d("private-view"),Q=i("tooltip");return s(),u(J,{title:"Key Manager"},{"title-outer:prepend":v(()=>[p(l,{class:"header-icon",rounded:"",disabled:"",icon:"",secondary:""},{default:v(()=>[p(n,{name:"key"})]),_:1})]),actions:v(()=>[c((s(),u(l,{rounded:"",icon:"",onClick:U},{default:v(()=>[p(n,{name:"add"})]),_:1})),[[Q,"Add Key",void 0,{bottom:!0}]])]),navigation:v(()=>[f("div",R,[p(n,{name:"lock"}),a[4]||(a[4]=f("span",null,"Manage Secrets",-1))])]),default:v(()=>[f("div",M,[g(" Loading "),w.value?(s(),y("div",N,[p(r,{indeterminate:""}),a[5]||(a[5]=f("p",null,"Loading keys...",-1))])):E.value?(s(),y(x,{key:1},[g(" Error "),p(t,{type:"danger"},{default:v(()=>[m(b(E.value),1)]),_:1})],2112)):0===_.value.length?(s(),y(x,{key:2},[g(" Empty state "),f("div",L,[p(n,{name:"vpn_key_off","x-large":""}),a[7]||(a[7]=f("h2",null,"No keys configured yet",-1)),a[8]||(a[8]=f("p",null,"Add your first key to get started with centralized secret management.",-1)),p(l,{onClick:U},{default:v(()=>[p(n,{name:"add",left:""}),a[6]||(a[6]=m(" Add Key ",-1))]),_:1})])],2112)):(s(),y(x,{key:3},[g(" Key Table "),f("div",F,[p(k,{headers:D,items:_.value,"show-resize":""},{"item.provider":v(({item:e})=>{return[f("div",{class:h(["provider-badge",`provider-${e.provider}`])},[p(n,{name:(a=e.provider,{database:"storage",file:"folder",env:"terminal",external:"cloud"}[a]??"help"),small:""},null,8,["name"]),f("span",null,b($(e.provider)),1)],2)];var a}),"item.source":v(({item:e})=>[e.source?(s(),y("code",I,b(e.source),1)):(s(),y("span",j,"— (stored value)"))]),"item.date_updated":v(({item:e})=>{return[p(o,{text:(a=e.date_updated,new Date(a).toLocaleString())},null,8,["text"])];var a}),"item.actions":v(({item:e})=>[f("div",O,[c((s(),u(l,{icon:"",rounded:"",secondary:"","x-small":"",onClick:a=>function(e){C.value=e}(e)},{default:v(()=>[p(n,{name:"edit"})]),_:1},8,["onClick"])),[[Q,"Edit Key"]]),c((s(),u(l,{icon:"",rounded:"",secondary:"","x-small":"",class:"delete-btn",onClick:a=>function(e){K.value=e}(e)},{default:v(()=>[p(n,{name:"delete"})]),_:1},8,["onClick"])),[[Q,"Delete Key"]])])]),_:1},8,["items"])])],2112))]),V.value?(s(),u(z,{key:0,"key-data":S.value,onClose:q,onSaved:Y},null,8,["key-data"])):g("v-if",!0),C.value?(s(),u(X,{key:1,"model-value":!!C.value,"onUpdate:modelValue":a[1]||(a[1]=e=>C.value=null)},{default:v(()=>[p(H,{class:"warn-dialog"},{default:v(()=>[p(T,null,{default:v(()=>[p(n,{name:"warning",class:"warn-icon"}),a[9]||(a[9]=m(" Edit Key — Proceed with Caution ",-1))]),_:1}),p(B,null,{default:v(()=>[f("p",null,[a[10]||(a[10]=m("You are about to edit ",-1)),f("strong",null,'"'+b(C.value?.name)+'"',1),a[11]||(a[11]=m(".",-1))]),a[12]||(a[12]=f("ul",{class:"warn-list"},[f("li",null,[m("Any service or extension currently using this key will receive the "),f("strong",null,"new value immediately"),m(".")]),f("li",null,[m("If the provider is changed, the existing stored value or source will be "),f("strong",null,"replaced"),m(".")]),f("li",null,[m("For "),f("em",null,"database"),m("-provider keys, leaving the value field blank will keep the existing encrypted value.")])],-1)),a[13]||(a[13]=f("p",{class:"warn-footer"},"Make sure you have coordinated this change with all consumers of this key before continuing.",-1))]),_:1}),p(G,null,{default:v(()=>[p(l,{secondary:"",onClick:a[0]||(a[0]=e=>C.value=null)},{default:v(()=>[...a[14]||(a[14]=[m("Cancel",-1)])]),_:1}),p(l,{onClick:P},{default:v(()=>[p(n,{name:"edit",left:""}),a[15]||(a[15]=m(" Continue to Edit ",-1))]),_:1})]),_:1})]),_:1})]),_:1},8,["model-value"])):g("v-if",!0),K.value?(s(),u(X,{key:2,"model-value":!!K.value,"onUpdate:modelValue":a[3]||(a[3]=e=>K.value=null)},{default:v(()=>[p(H,null,{default:v(()=>[p(T,null,{default:v(()=>[...a[16]||(a[16]=[m("Delete Key",-1)])]),_:1}),p(B,null,{default:v(()=>[a[17]||(a[17]=m(" Are you sure you want to delete ",-1)),f("strong",null,'"'+b(K.value?.name)+'"',1),a[18]||(a[18]=m("? This action cannot be undone. ",-1))]),_:1}),p(G,null,{default:v(()=>[p(l,{secondary:"",onClick:a[2]||(a[2]=e=>K.value=null)},{default:v(()=>[...a[19]||(a[19]=[m("Cancel",-1)])]),_:1}),p(l,{kind:"danger",loading:A.value,onClick:W},{default:v(()=>[...a[20]||(a[20]=[m("Delete",-1)])]),_:1},8,["loading"])]),_:1})]),_:1})]),_:1},8,["model-value"])):g("v-if",!0)]),_:1})}}});P("\n.key-manager-layout[data-v-b322b5fb] {\n padding: var(--content-padding);\n max-width: 1200px;\n}\n.nav-info[data-v-b322b5fb] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n color: var(--foreground-subdued);\n font-size: 13px;\n}\n.loading-state[data-v-b322b5fb] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 16px;\n padding: 64px;\n color: var(--foreground-subdued);\n}\n.empty-state[data-v-b322b5fb] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 80px 40px;\n text-align: center;\n color: var(--foreground-subdued);\n}\n.empty-state h2[data-v-b322b5fb] {\n margin: 0;\n font-size: 20px;\n color: var(--foreground-normal);\n}\n.empty-state p[data-v-b322b5fb] {\n max-width: 400px;\n margin: 0;\n line-height: 1.6;\n}\n.key-table-wrapper[data-v-b322b5fb] {\n background: var(--background-normal);\n border-radius: var(--border-radius);\n border: 1px solid var(--border-normal);\n overflow: hidden;\n}\n.provider-badge[data-v-b322b5fb] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 2px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n.provider-database[data-v-b322b5fb] { background: #e8f5e9; color: #2e7d32;\n}\n.provider-file[data-v-b322b5fb] { background: #fff3e0; color: #e65100;\n}\n.provider-env[data-v-b322b5fb] { background: #e3f2fd; color: #1565c0;\n}\n.provider-external[data-v-b322b5fb] { background: #f3e5f5; color: #6a1b9a;\n}\n.source-code[data-v-b322b5fb] {\n font-family: var(--family-monospace);\n font-size: 12px;\n background: var(--background-subdued);\n padding: 2px 6px;\n border-radius: 4px;\n}\n.muted[data-v-b322b5fb] {\n color: var(--foreground-subdued);\n font-style: italic;\n font-size: 13px;\n}\n.row-actions[data-v-b322b5fb] {\n display: flex;\n gap: 4px;\n justify-content: flex-end;\n}\n.delete-btn[data-v-b322b5fb] {\n --v-button-color: var(--danger);\n --v-button-color-hover: var(--danger);\n}\n\n/* Edit warning dialog */\n.warn-dialog .v-card-title[data-v-b322b5fb] {\n display: flex;\n align-items: center;\n gap: 10px;\n color: var(--warning);\n}\n.warn-icon[data-v-b322b5fb] {\n color: var(--warning);\n flex-shrink: 0;\n}\n.warn-list[data-v-b322b5fb] {\n margin: 12px 0;\n padding-left: 20px;\n line-height: 1.8;\n color: var(--foreground-normal);\n}\n.warn-list li[data-v-b322b5fb] {\n margin-bottom: 4px;\n}\n.warn-footer[data-v-b322b5fb] {\n margin: 12px 0 0;\n font-size: 13px;\n color: var(--warning);\n font-style: italic;\n}\n",{});const W=[],$=[],B=[],G=[n({id:"key-manager",name:"Key Manager",icon:"key",routes:[{path:"",component:q(Y,[["__scopeId","data-v-b322b5fb"],["__file","KeyList.vue"]])}]})],H=[],X=[],J=[];export{$ as displays,W as interfaces,B as layouts,G as modules,J as operations,H as panels,X as themes};
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "directus-extension-key",
3
+ "version": "0.1.2",
4
+ "description": "Centralized and secure key management extension for Directus",
5
+ "author": {
6
+ "name": "Ankit Chauhan",
7
+ "email": "ankitchauhan246@gmail.com"
8
+ },
9
+ "keywords": [
10
+ "directus",
11
+ "extension",
12
+ "key-management",
13
+ "secrets",
14
+ "key",
15
+ "token",
16
+ "encryption"
17
+ ],
18
+ "files": [
19
+ "dist",
20
+ "package.json",
21
+ "README.md"
22
+ ],
23
+ "license": "gpl-3.0",
24
+ "scripts": {
25
+ "build": "directus-extension build",
26
+ "dev": "directus-extension build --watch",
27
+ "prepublishOnly": "npm run build"
28
+ },
29
+ "directus:extension": {
30
+ "type": "bundle",
31
+ "path": {
32
+ "app": "dist/app.js",
33
+ "api": "dist/api.js"
34
+ },
35
+ "entries": [
36
+ {
37
+ "type": "hook",
38
+ "name": "key-hook",
39
+ "source": "src/api/hook/index.ts"
40
+ },
41
+ {
42
+ "type": "endpoint",
43
+ "name": "key-endpoint",
44
+ "source": "src/api/endpoint/index.ts"
45
+ },
46
+ {
47
+ "type": "module",
48
+ "name": "key-module",
49
+ "source": "src/module/index.ts"
50
+ }
51
+ ],
52
+ "host": ">=10.0.0"
53
+ },
54
+ "dependencies": {
55
+ "node-fetch": "^3.3.2"
56
+ },
57
+ "devDependencies": {
58
+ "@directus/extensions-sdk": "^12.0.0",
59
+ "@types/node": "^20.0.0",
60
+ "typescript": "^5.0.0",
61
+ "vue": "^3.4.0"
62
+ }
63
+ }