├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── dist └── index.js ├── package-lock.json ├── package.json ├── src └── index.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | docker-compose.yml 4 | data.db -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | src 3 | .gitignore 4 | data.db 5 | docker-compose.yml 6 | tsconfig.json -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Brainslug 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Directus Extension Block Endpoints 2 | As the name suggests this extension will allow you to block any endpoint with a custom message. 3 | 4 | > Tested with Directus 10.10.4 5 | 6 | > Note: blocking `/server/info` seems to break the app in > 9.23.1 7 | ## Installation 8 | 9 | The package is published to npm: 10 | `npm install directus-extension-block-endpoints` 11 | 12 | **Manual Installation** 13 | - Download or fork the repository 14 | - Install the requirements\ 15 | `npm install` 16 | - Build the extension\ 17 | `npm run build` 18 | - Move the result to your extension folder\ 19 | `mv dist extensions/hooks/directus-extension-block-endpoints` 20 | - Add required environment variables (see below) 21 | - Restart your Directus instance 22 | 23 | ## Environment Variables 24 | | name | type | default | example | 25 | |---------------------------|------------------|------------------------------------------------|--------------------| 26 | | BLOCKED_ENDPOINTS_ENABLED | boolean | true | | 27 | | BLOCKED_ENDPOINTS_PATHS | string\|string[] | | /server/info,/test | 28 | | BLOCKED_ENDPOINTS_STATUS | number | 418 | 401 | 29 | | BLOCKED_ENDPOINTS_TYPE | string | application/json | | 30 | | BLOCKED_ENDPOINTS_BODY | string | { "error": "Page blocked! I\'m a teapot now" } | | 31 | 32 | ## Usages 33 | 34 | > warning: This will only block GET requests! but the script should be easy to modify to any METHOD you want (making it configurable seemed like a mess) 35 | 36 | To block `/server/info` from exposing info when using Directus API only: 37 | 38 | **ENV** 39 | ``` 40 | BLOCKED_ENDPOINTS_PATHS="/server/info" 41 | BLOCKED_ENDPOINTS_STATUS=401 42 | BLOCKED_ENDPOINTS_TYPE="text/plain" 43 | BLOCKED_ENDPOINTS_BODY="Access Denied!!" 44 | ``` 45 | **REQUEST** 46 | ``` 47 | GET /server/info 48 | Access Denied!! 49 | -> 401 50 | ``` 51 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | var e,t;!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]])),s={};for(const e of a)s[e]=t[e];return e.objectValues(s)},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 a=e.arrayToEnum(["string","nan","number","integer","float","boolean","date","bigint","symbol","function","undefined","null","array","object","unknown","promise","void","never","map","set"]),s=e=>{switch(typeof e){case"undefined":return a.undefined;case"string":return a.string;case"number":return isNaN(e)?a.nan:a.number;case"boolean":return a.boolean;case"function":return a.function;case"bigint":return a.bigint;case"symbol":return a.symbol;case"object":return Array.isArray(e)?a.array:null===e?a.null:e.then&&"function"==typeof e.then&&e.catch&&"function"==typeof e.catch?a.promise:"undefined"!=typeof Map&&e instanceof Map?a.map:"undefined"!=typeof Set&&e instanceof Set?a.set:"undefined"!=typeof Date&&e instanceof Date?a.date:a.object;default:return a.unknown}},n=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 r 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:[]},s=e=>{for(const n of e.issues)if("invalid_union"===n.code)n.unionErrors.map(s);else if("invalid_return_type"===n.code)s(n.returnTypeError);else if("invalid_arguments"===n.code)s(n.argumentsError);else if(0===n.path.length)a._errors.push(t(n));else{let e=a,s=0;for(;se.message)){const t={},a=[];for(const s of this.issues)s.path.length>0?(t[s.path[0]]=t[s.path[0]]||[],t[s.path[0]].push(e(s))):a.push(e(s));return{formErrors:a,fieldErrors:t}}get formErrors(){return this.flatten()}}r.create=e=>new r(e);const i=(t,s)=>{let r;switch(t.code){case n.invalid_type:r=t.received===a.undefined?"Required":`Expected ${t.expected}, received ${t.received}`;break;case n.invalid_literal:r=`Invalid literal value, expected ${JSON.stringify(t.expected,e.jsonStringifyReplacer)}`;break;case n.unrecognized_keys:r=`Unrecognized key(s) in object: ${e.joinValues(t.keys,", ")}`;break;case n.invalid_union:r="Invalid input";break;case n.invalid_union_discriminator:r=`Invalid discriminator value. Expected ${e.joinValues(t.options)}`;break;case n.invalid_enum_value:r=`Invalid enum value. Expected ${e.joinValues(t.options)}, received '${t.received}'`;break;case n.invalid_arguments:r="Invalid function arguments";break;case n.invalid_return_type:r="Invalid function return type";break;case n.invalid_date:r="Invalid date";break;case n.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 n.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 n.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 n.custom:r="Invalid input";break;case n.invalid_intersection_types:r="Intersection results could not be merged";break;case n.not_multiple_of:r=`Number must be a multiple of ${t.multipleOf}`;break;case n.not_finite:r="Number must be finite";break;default:r=s.defaultError,e.assertNever(t)}return{message:r}};let o=i;function d(){return o}const c=e=>{const{data:t,path:a,errorMaps:s,issueData:n}=e,r=[...a,...n.path||[]],i={...n,path:r};let o="";const d=s.filter((e=>!!e)).slice().reverse();for(const e of d)o=e(i,{data:t,defaultError:o}).message;return{...n,path:r,message:n.message||o}};function u(e,t){const a=c({issueData:t,data:e.data,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,d(),i].filter((e=>!!e))});e.common.issues.push(a)}class l{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 s of t){if("aborted"===s.status)return p;"dirty"===s.status&&e.dirty(),a.push(s.value)}return{status:e.value,value:a}}static async mergeObjectAsync(e,t){const a=[];for(const e of t)a.push({key:await e.key,value:await e.value});return l.mergeObjectSync(e,a)}static mergeObjectSync(e,t){const a={};for(const s of t){const{key:t,value:n}=s;if("aborted"===t.status)return p;if("aborted"===n.status)return p;"dirty"===t.status&&e.dirty(),"dirty"===n.status&&e.dirty(),"__proto__"===t.value||void 0===n.value&&!s.alwaysSet||(a[t.value]=n.value)}return{status:e.value,value:a}}}const p=Object.freeze({status:"aborted"}),h=e=>({status:"dirty",value:e}),m=e=>({status:"valid",value:e}),f=e=>"aborted"===e.status,y=e=>"dirty"===e.status,_=e=>"valid"===e.status,v=e=>"undefined"!=typeof Promise&&e instanceof Promise;var g;!function(e){e.errToObj=e=>"string"==typeof e?{message:e}:e||{},e.toString=e=>"string"==typeof e?e:null==e?void 0:e.message}(g||(g={}));class x{constructor(e,t,a,s){this._cachedPath=[],this.parent=e,this.data=t,this._path=a,this._key=s}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 b=(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 r(e.common.issues);return this._error=t,this._error}}};function k(e){if(!e)return{};const{errorMap:t,invalid_type_error:a,required_error:s,description:n}=e;if(t&&(a||s))throw new Error('Can\'t use "invalid_type_error" or "required_error" in conjunction with custom error map.');if(t)return{errorMap:t,description:n};return{errorMap:(e,t)=>"invalid_type"!==e.code?{message:t.defaultError}:void 0===t.data?{message:null!=s?s:t.defaultError}:{message:null!=a?a:t.defaultError},description:n}}class w{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 s(e.data)}_getOrReturnCtx(e,t){return t||{common:e.parent.common,data:e.data,parsedType:s(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}_processInputParams(e){return{status:new l,ctx:{common:e.parent.common,data:e.data,parsedType:s(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}}_parseSync(e){const t=this._parse(e);if(v(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 n={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:s(e)},r=this._parseSync({data:e,path:n.path,parent:n});return b(n,r)}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:s(e)},n=this._parse({data:e,path:a.path,parent:a}),r=await(v(n)?n:Promise.resolve(n));return b(a,r)}refine(e,t){const a=e=>"string"==typeof t||void 0===t?{message:t}:"function"==typeof t?t(e):t;return this._refinement(((t,s)=>{const r=e(t),i=()=>s.addIssue({code:n.custom,...a(t)});return"undefined"!=typeof Promise&&r instanceof Promise?r.then((e=>!!e||(i(),!1))):!!r||(i(),!1)}))}refinement(e,t){return this._refinement(((a,s)=>!!e(a)||(s.addIssue("function"==typeof t?t(a,s):t),!1)))}_refinement(e){return new ue({schema:this,typeName:ke.ZodEffects,effect:{type:"refinement",refinement:e}})}superRefine(e){return this._refinement(e)}optional(){return le.create(this,this._def)}nullable(){return pe.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return F.create(this,this._def)}promise(){return ce.create(this,this._def)}or(e){return H.create([this,e],this._def)}and(e){return X.create(this,e,this._def)}transform(e){return new ue({...k(this._def),schema:this,typeName:ke.ZodEffects,effect:{type:"transform",transform:e}})}default(e){const t="function"==typeof e?e:()=>e;return new he({...k(this._def),innerType:this,defaultValue:t,typeName:ke.ZodDefault})}brand(){return new _e({typeName:ke.ZodBranded,type:this,...k(this._def)})}catch(e){const t="function"==typeof e?e:()=>e;return new me({...k(this._def),innerType:this,catchValue:t,typeName:ke.ZodCatch})}describe(e){return new(0,this.constructor)({...this._def,description:e})}pipe(e){return ve.create(this,e)}readonly(){return ge.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}}const Z=/^c[^\s-]{8,}$/i,T=/^[a-z][a-z0-9]*$/,O=/^[0-9A-HJKMNP-TV-Z]{26}$/,N=/^[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,E=/^(?!\.)(?!.*\.\.)([A-Z0-9_+-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i;let S;const C=/^(((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}))$/,j=/^(([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})))$/;class I extends w{_parse(t){this._def.coerce&&(t.data=String(t.data));if(this._getType(t)!==a.string){const e=this._getOrReturnCtx(t);return u(e,{code:n.invalid_type,expected:a.string,received:e.parsedType}),p}const s=new l;let r;for(const a of this._def.checks)if("min"===a.kind)t.data.lengtha.value&&(r=this._getOrReturnCtx(t,r),u(r,{code:n.too_big,maximum:a.value,type:"string",inclusive:!0,exact:!1,message:a.message}),s.dirty());else if("length"===a.kind){const e=t.data.length>a.value,i=t.data.lengthe.test(t)),{validation:t,code:n.invalid_string,...g.errToObj(a)})}_addCheck(e){return new I({...this._def,checks:[...this._def.checks,e]})}email(e){return this._addCheck({kind:"email",...g.errToObj(e)})}url(e){return this._addCheck({kind:"url",...g.errToObj(e)})}emoji(e){return this._addCheck({kind:"emoji",...g.errToObj(e)})}uuid(e){return this._addCheck({kind:"uuid",...g.errToObj(e)})}cuid(e){return this._addCheck({kind:"cuid",...g.errToObj(e)})}cuid2(e){return this._addCheck({kind:"cuid2",...g.errToObj(e)})}ulid(e){return this._addCheck({kind:"ulid",...g.errToObj(e)})}ip(e){return this._addCheck({kind:"ip",...g.errToObj(e)})}datetime(e){var t;return"string"==typeof e?this._addCheck({kind:"datetime",precision:null,offset:!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,...g.errToObj(null==e?void 0:e.message)})}regex(e,t){return this._addCheck({kind:"regex",regex:e,...g.errToObj(t)})}includes(e,t){return this._addCheck({kind:"includes",value:e,position:null==t?void 0:t.position,...g.errToObj(null==t?void 0:t.message)})}startsWith(e,t){return this._addCheck({kind:"startsWith",value:e,...g.errToObj(t)})}endsWith(e,t){return this._addCheck({kind:"endsWith",value:e,...g.errToObj(t)})}min(e,t){return this._addCheck({kind:"min",value:e,...g.errToObj(t)})}max(e,t){return this._addCheck({kind:"max",value:e,...g.errToObj(t)})}length(e,t){return this._addCheck({kind:"length",value:e,...g.errToObj(t)})}nonempty(e){return this.min(1,g.errToObj(e))}trim(){return new I({...this._def,checks:[...this._def.checks,{kind:"trim"}]})}toLowerCase(){return new I({...this._def,checks:[...this._def.checks,{kind:"toLowerCase"}]})}toUpperCase(){return new I({...this._def,checks:[...this._def.checks,{kind:"toUpperCase"}]})}get isDatetime(){return!!this._def.checks.find((e=>"datetime"===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 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 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.values?a:s;return parseInt(e.toFixed(n).replace(".",""))%parseInt(t.toFixed(n).replace(".",""))/Math.pow(10,n)}I.create=e=>{var t;return new I({checks:[],typeName:ke.ZodString,coerce:null!==(t=null==e?void 0:e.coerce)&&void 0!==t&&t,...k(e)})};class R extends w{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)!==a.number){const e=this._getOrReturnCtx(t);return u(e,{code:n.invalid_type,expected:a.number,received:e.parsedType}),p}let s;const r=new l;for(const a of this._def.checks)if("int"===a.kind)e.isInteger(t.data)||(s=this._getOrReturnCtx(t,s),u(s,{code:n.invalid_type,expected:"integer",received:"float",message:a.message}),r.dirty());else if("min"===a.kind){(a.inclusive?t.dataa.value:t.data>=a.value)&&(s=this._getOrReturnCtx(t,s),u(s,{code:n.too_big,maximum:a.value,type:"number",inclusive:a.inclusive,exact:!1,message:a.message}),r.dirty())}else"multipleOf"===a.kind?0!==P(t.data,a.value)&&(s=this._getOrReturnCtx(t,s),u(s,{code:n.not_multiple_of,multipleOf:a.value,message:a.message}),r.dirty()):"finite"===a.kind?Number.isFinite(t.data)||(s=this._getOrReturnCtx(t,s),u(s,{code:n.not_finite,message:a.message}),r.dirty()):e.assertNever(a);return{status:r.value,value:t.data}}gte(e,t){return this.setLimit("min",e,!0,g.toString(t))}gt(e,t){return this.setLimit("min",e,!1,g.toString(t))}lte(e,t){return this.setLimit("max",e,!0,g.toString(t))}lt(e,t){return this.setLimit("max",e,!1,g.toString(t))}setLimit(e,t,a,s){return new R({...this._def,checks:[...this._def.checks,{kind:e,value:t,inclusive:a,message:g.toString(s)}]})}_addCheck(e){return new R({...this._def,checks:[...this._def.checks,e]})}int(e){return this._addCheck({kind:"int",message:g.toString(e)})}positive(e){return this._addCheck({kind:"min",value:0,inclusive:!1,message:g.toString(e)})}negative(e){return this._addCheck({kind:"max",value:0,inclusive:!1,message:g.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:0,inclusive:!0,message:g.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:0,inclusive:!0,message:g.toString(e)})}multipleOf(e,t){return this._addCheck({kind:"multipleOf",value:e,message:g.toString(t)})}finite(e){return this._addCheck({kind:"finite",message:g.toString(e)})}safe(e){return this._addCheck({kind:"min",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:g.toString(e)})._addCheck({kind:"max",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:g.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"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.valuenew R({checks:[],typeName:ke.ZodNumber,coerce:(null==e?void 0:e.coerce)||!1,...k(e)});class A extends w{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)!==a.bigint){const e=this._getOrReturnCtx(t);return u(e,{code:n.invalid_type,expected:a.bigint,received:e.parsedType}),p}let s;const r=new l;for(const a of this._def.checks)if("min"===a.kind){(a.inclusive?t.dataa.value:t.data>=a.value)&&(s=this._getOrReturnCtx(t,s),u(s,{code:n.too_big,type:"bigint",maximum:a.value,inclusive:a.inclusive,message:a.message}),r.dirty())}else"multipleOf"===a.kind?t.data%a.value!==BigInt(0)&&(s=this._getOrReturnCtx(t,s),u(s,{code:n.not_multiple_of,multipleOf:a.value,message:a.message}),r.dirty()):e.assertNever(a);return{status:r.value,value:t.data}}gte(e,t){return this.setLimit("min",e,!0,g.toString(t))}gt(e,t){return this.setLimit("min",e,!1,g.toString(t))}lte(e,t){return this.setLimit("max",e,!0,g.toString(t))}lt(e,t){return this.setLimit("max",e,!1,g.toString(t))}setLimit(e,t,a,s){return new A({...this._def,checks:[...this._def.checks,{kind:e,value:t,inclusive:a,message:g.toString(s)}]})}_addCheck(e){return new A({...this._def,checks:[...this._def.checks,e]})}positive(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!1,message:g.toString(e)})}negative(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!1,message:g.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!0,message:g.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!0,message:g.toString(e)})}multipleOf(e,t){return this._addCheck({kind:"multipleOf",value:e,message:g.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{var t;return new A({checks:[],typeName:ke.ZodBigInt,coerce:null!==(t=null==e?void 0:e.coerce)&&void 0!==t&&t,...k(e)})};class D extends w{_parse(e){this._def.coerce&&(e.data=Boolean(e.data));if(this._getType(e)!==a.boolean){const t=this._getOrReturnCtx(e);return u(t,{code:n.invalid_type,expected:a.boolean,received:t.parsedType}),p}return m(e.data)}}D.create=e=>new D({typeName:ke.ZodBoolean,coerce:(null==e?void 0:e.coerce)||!1,...k(e)});class L extends w{_parse(t){this._def.coerce&&(t.data=new Date(t.data));if(this._getType(t)!==a.date){const e=this._getOrReturnCtx(t);return u(e,{code:n.invalid_type,expected:a.date,received:e.parsedType}),p}if(isNaN(t.data.getTime())){return u(this._getOrReturnCtx(t),{code:n.invalid_date}),p}const s=new l;let r;for(const a of this._def.checks)"min"===a.kind?t.data.getTime()a.value&&(r=this._getOrReturnCtx(t,r),u(r,{code:n.too_big,message:a.message,inclusive:!0,exact:!1,maximum:a.value,type:"date"}),s.dirty()):e.assertNever(a);return{status:s.value,value:new Date(t.data.getTime())}}_addCheck(e){return new L({...this._def,checks:[...this._def.checks,e]})}min(e,t){return this._addCheck({kind:"min",value:e.getTime(),message:g.toString(t)})}max(e,t){return this._addCheck({kind:"max",value:e.getTime(),message:g.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.valuenew L({checks:[],coerce:(null==e?void 0:e.coerce)||!1,typeName:ke.ZodDate,...k(e)});class $ extends w{_parse(e){if(this._getType(e)!==a.symbol){const t=this._getOrReturnCtx(e);return u(t,{code:n.invalid_type,expected:a.symbol,received:t.parsedType}),p}return m(e.data)}}$.create=e=>new $({typeName:ke.ZodSymbol,...k(e)});class M extends w{_parse(e){if(this._getType(e)!==a.undefined){const t=this._getOrReturnCtx(e);return u(t,{code:n.invalid_type,expected:a.undefined,received:t.parsedType}),p}return m(e.data)}}M.create=e=>new M({typeName:ke.ZodUndefined,...k(e)});class V extends w{_parse(e){if(this._getType(e)!==a.null){const t=this._getOrReturnCtx(e);return u(t,{code:n.invalid_type,expected:a.null,received:t.parsedType}),p}return m(e.data)}}V.create=e=>new V({typeName:ke.ZodNull,...k(e)});class z extends w{constructor(){super(...arguments),this._any=!0}_parse(e){return m(e.data)}}z.create=e=>new z({typeName:ke.ZodAny,...k(e)});class U extends w{constructor(){super(...arguments),this._unknown=!0}_parse(e){return m(e.data)}}U.create=e=>new U({typeName:ke.ZodUnknown,...k(e)});class K extends w{_parse(e){const t=this._getOrReturnCtx(e);return u(t,{code:n.invalid_type,expected:a.never,received:t.parsedType}),p}}K.create=e=>new K({typeName:ke.ZodNever,...k(e)});class B extends w{_parse(e){if(this._getType(e)!==a.undefined){const t=this._getOrReturnCtx(e);return u(t,{code:n.invalid_type,expected:a.void,received:t.parsedType}),p}return m(e.data)}}B.create=e=>new B({typeName:ke.ZodVoid,...k(e)});class F extends w{_parse(e){const{ctx:t,status:s}=this._processInputParams(e),r=this._def;if(t.parsedType!==a.array)return u(t,{code:n.invalid_type,expected:a.array,received:t.parsedType}),p;if(null!==r.exactLength){const e=t.data.length>r.exactLength.value,a=t.data.lengthr.maxLength.value&&(u(t,{code:n.too_big,maximum:r.maxLength.value,type:"array",inclusive:!0,exact:!1,message:r.maxLength.message}),s.dirty()),t.common.async)return Promise.all([...t.data].map(((e,a)=>r.type._parseAsync(new x(t,e,t.path,a))))).then((e=>l.mergeArray(s,e)));const i=[...t.data].map(((e,a)=>r.type._parseSync(new x(t,e,t.path,a))));return l.mergeArray(s,i)}get element(){return this._def.type}min(e,t){return new F({...this._def,minLength:{value:e,message:g.toString(t)}})}max(e,t){return new F({...this._def,maxLength:{value:e,message:g.toString(t)}})}length(e,t){return new F({...this._def,exactLength:{value:e,message:g.toString(t)}})}nonempty(e){return this.min(1,e)}}function q(e){if(e instanceof W){const t={};for(const a in e.shape){const s=e.shape[a];t[a]=le.create(q(s))}return new W({...e._def,shape:()=>t})}return e instanceof F?new F({...e._def,type:q(e.element)}):e instanceof le?le.create(q(e.unwrap())):e instanceof pe?pe.create(q(e.unwrap())):e instanceof Q?Q.create(e.items.map((e=>q(e)))):e}F.create=(e,t)=>new F({type:e,minLength:null,maxLength:null,exactLength:null,typeName:ke.ZodArray,...k(t)});class W extends w{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)!==a.object){const t=this._getOrReturnCtx(e);return u(t,{code:n.invalid_type,expected:a.object,received:t.parsedType}),p}const{status:t,ctx:s}=this._processInputParams(e),{shape:r,keys:i}=this._getCached(),o=[];if(!(this._def.catchall instanceof K&&"strip"===this._def.unknownKeys))for(const e in s.data)i.includes(e)||o.push(e);const d=[];for(const e of i){const t=r[e],a=s.data[e];d.push({key:{status:"valid",value:e},value:t._parse(new x(s,a,s.path,e)),alwaysSet:e in s.data})}if(this._def.catchall instanceof K){const e=this._def.unknownKeys;if("passthrough"===e)for(const e of o)d.push({key:{status:"valid",value:e},value:{status:"valid",value:s.data[e]}});else if("strict"===e)o.length>0&&(u(s,{code:n.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 a=s.data[t];d.push({key:{status:"valid",value:t},value:e._parse(new x(s,a,s.path,t)),alwaysSet:t in s.data})}}return s.common.async?Promise.resolve().then((async()=>{const e=[];for(const t of d){const a=await t.key;e.push({key:a,value:await t.value,alwaysSet:t.alwaysSet})}return e})).then((e=>l.mergeObjectSync(t,e))):l.mergeObjectSync(t,d)}get shape(){return this._def.shape()}strict(e){return g.errToObj,new W({...this._def,unknownKeys:"strict",...void 0!==e?{errorMap:(t,a)=>{var s,n,r,i;const o=null!==(r=null===(n=(s=this._def).errorMap)||void 0===n?void 0:n.call(s,t,a).message)&&void 0!==r?r:a.defaultError;return"unrecognized_keys"===t.code?{message:null!==(i=g.errToObj(e).message)&&void 0!==i?i:o}:{message:o}}}:{}})}strip(){return new W({...this._def,unknownKeys:"strip"})}passthrough(){return new W({...this._def,unknownKeys:"passthrough"})}extend(e){return new W({...this._def,shape:()=>({...this._def.shape(),...e})})}merge(e){return new W({unknownKeys:e._def.unknownKeys,catchall:e._def.catchall,shape:()=>({...this._def.shape(),...e._def.shape()}),typeName:ke.ZodObject})}setKey(e,t){return this.augment({[e]:t})}catchall(e){return new W({...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 W({...this._def,shape:()=>a})}omit(t){const a={};return e.objectKeys(this.shape).forEach((e=>{t[e]||(a[e]=this.shape[e])})),new W({...this._def,shape:()=>a})}deepPartial(){return q(this)}partial(t){const a={};return e.objectKeys(this.shape).forEach((e=>{const s=this.shape[e];t&&!t[e]?a[e]=s:a[e]=s.optional()})),new W({...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 le;)t=t._def.innerType;a[e]=t}})),new W({...this._def,shape:()=>a})}keyof(){return ie(e.objectKeys(this.shape))}}W.create=(e,t)=>new W({shape:()=>e,unknownKeys:"strip",catchall:K.create(),typeName:ke.ZodObject,...k(t)}),W.strictCreate=(e,t)=>new W({shape:()=>e,unknownKeys:"strict",catchall:K.create(),typeName:ke.ZodObject,...k(t)}),W.lazycreate=(e,t)=>new W({shape:e,unknownKeys:"strip",catchall:K.create(),typeName:ke.ZodObject,...k(t)});class H extends w{_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 r(e.ctx.common.issues)));return u(t,{code:n.invalid_union,unionErrors:a}),p}));{let e;const s=[];for(const n of a){const a={...t,common:{...t.common,issues:[]},parent:null},r=n._parseSync({data:t.data,path:t.path,parent:a});if("valid"===r.status)return r;"dirty"!==r.status||e||(e={result:r,ctx:a}),a.common.issues.length&&s.push(a.common.issues)}if(e)return t.common.issues.push(...e.ctx.common.issues),e.result;const i=s.map((e=>new r(e)));return u(t,{code:n.invalid_union,unionErrors:i}),p}}get options(){return this._def.options}}H.create=(e,t)=>new H({options:e,typeName:ke.ZodUnion,...k(t)});const J=e=>e instanceof ne?J(e.schema):e instanceof ue?J(e.innerType()):e instanceof re?[e.value]:e instanceof oe?e.options:e instanceof de?Object.keys(e.enum):e instanceof he?J(e._def.innerType):e instanceof M?[void 0]:e instanceof V?[null]:null;class Y extends w{_parse(e){const{ctx:t}=this._processInputParams(e);if(t.parsedType!==a.object)return u(t,{code:n.invalid_type,expected:a.object,received:t.parsedType}),p;const s=this.discriminator,r=t.data[s],i=this.optionsMap.get(r);return i?t.common.async?i._parseAsync({data:t.data,path:t.path,parent:t}):i._parseSync({data:t.data,path:t.path,parent:t}):(u(t,{code:n.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[s]}),p)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(e,t,a){const s=new Map;for(const a of t){const t=J(a.shape[e]);if(!t)throw new Error(`A discriminator value for key \`${e}\` could not be extracted from all schema options`);for(const n of t){if(s.has(n))throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(n)}`);s.set(n,a)}}return new Y({typeName:ke.ZodDiscriminatedUnion,discriminator:e,options:t,optionsMap:s,...k(a)})}}function G(t,n){const r=s(t),i=s(n);if(t===n)return{valid:!0,data:t};if(r===a.object&&i===a.object){const a=e.objectKeys(n),s=e.objectKeys(t).filter((e=>-1!==a.indexOf(e))),r={...t,...n};for(const e of s){const a=G(t[e],n[e]);if(!a.valid)return{valid:!1};r[e]=a.data}return{valid:!0,data:r}}if(r===a.array&&i===a.array){if(t.length!==n.length)return{valid:!1};const e=[];for(let a=0;a{if(f(e)||f(s))return p;const r=G(e.value,s.value);return r.valid?((y(e)||y(s))&&t.dirty(),{status:t.value,value:r.data}):(u(a,{code:n.invalid_intersection_types}),p)};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])=>s(e,t))):s(this._def.left._parseSync({data:a.data,path:a.path,parent:a}),this._def.right._parseSync({data:a.data,path:a.path,parent:a}))}}X.create=(e,t,a)=>new X({left:e,right:t,typeName:ke.ZodIntersection,...k(a)});class Q extends w{_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==a.array)return u(s,{code:n.invalid_type,expected:a.array,received:s.parsedType}),p;if(s.data.lengththis._def.items.length&&(u(s,{code:n.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:"array"}),t.dirty());const r=[...s.data].map(((e,t)=>{const a=this._def.items[t]||this._def.rest;return a?a._parse(new x(s,e,s.path,t)):null})).filter((e=>!!e));return s.common.async?Promise.all(r).then((e=>l.mergeArray(t,e))):l.mergeArray(t,r)}get items(){return this._def.items}rest(e){return new Q({...this._def,rest:e})}}Q.create=(e,t)=>{if(!Array.isArray(e))throw new Error("You must pass an array of schemas to z.tuple([ ... ])");return new Q({items:e,typeName:ke.ZodTuple,rest:null,...k(t)})};class ee extends w{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==a.object)return u(s,{code:n.invalid_type,expected:a.object,received:s.parsedType}),p;const r=[],i=this._def.keyType,o=this._def.valueType;for(const e in s.data)r.push({key:i._parse(new x(s,e,s.path,e)),value:o._parse(new x(s,s.data[e],s.path,e))});return s.common.async?l.mergeObjectAsync(t,r):l.mergeObjectSync(t,r)}get element(){return this._def.valueType}static create(e,t,a){return new ee(t instanceof w?{keyType:e,valueType:t,typeName:ke.ZodRecord,...k(a)}:{keyType:I.create(),valueType:e,typeName:ke.ZodRecord,...k(t)})}}class te extends w{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==a.map)return u(s,{code:n.invalid_type,expected:a.map,received:s.parsedType}),p;const r=this._def.keyType,i=this._def.valueType,o=[...s.data.entries()].map((([e,t],a)=>({key:r._parse(new x(s,e,s.path,[a,"key"])),value:i._parse(new x(s,t,s.path,[a,"value"]))})));if(s.common.async){const e=new Map;return Promise.resolve().then((async()=>{for(const a of o){const s=await a.key,n=await a.value;if("aborted"===s.status||"aborted"===n.status)return p;"dirty"!==s.status&&"dirty"!==n.status||t.dirty(),e.set(s.value,n.value)}return{status:t.value,value:e}}))}{const e=new Map;for(const a of o){const s=a.key,n=a.value;if("aborted"===s.status||"aborted"===n.status)return p;"dirty"!==s.status&&"dirty"!==n.status||t.dirty(),e.set(s.value,n.value)}return{status:t.value,value:e}}}}te.create=(e,t,a)=>new te({valueType:t,keyType:e,typeName:ke.ZodMap,...k(a)});class ae extends w{_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==a.set)return u(s,{code:n.invalid_type,expected:a.set,received:s.parsedType}),p;const r=this._def;null!==r.minSize&&s.data.sizer.maxSize.value&&(u(s,{code:n.too_big,maximum:r.maxSize.value,type:"set",inclusive:!0,exact:!1,message:r.maxSize.message}),t.dirty());const i=this._def.valueType;function o(e){const a=new Set;for(const s of e){if("aborted"===s.status)return p;"dirty"===s.status&&t.dirty(),a.add(s.value)}return{status:t.value,value:a}}const d=[...s.data.values()].map(((e,t)=>i._parse(new x(s,e,s.path,t))));return s.common.async?Promise.all(d).then((e=>o(e))):o(d)}min(e,t){return new ae({...this._def,minSize:{value:e,message:g.toString(t)}})}max(e,t){return new ae({...this._def,maxSize:{value:e,message:g.toString(t)}})}size(e,t){return this.min(e,t).max(e,t)}nonempty(e){return this.min(1,e)}}ae.create=(e,t)=>new ae({valueType:e,minSize:null,maxSize:null,typeName:ke.ZodSet,...k(t)});class se extends w{constructor(){super(...arguments),this.validate=this.implement}_parse(e){const{ctx:t}=this._processInputParams(e);if(t.parsedType!==a.function)return u(t,{code:n.invalid_type,expected:a.function,received:t.parsedType}),p;function s(e,a){return c({data:e,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,d(),i].filter((e=>!!e)),issueData:{code:n.invalid_arguments,argumentsError:a}})}function o(e,a){return c({data:e,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,d(),i].filter((e=>!!e)),issueData:{code:n.invalid_return_type,returnTypeError:a}})}const l={errorMap:t.common.contextualErrorMap},h=t.data;if(this._def.returns instanceof ce){const e=this;return m((async function(...t){const a=new r([]),n=await e._def.args.parseAsync(t,l).catch((e=>{throw a.addIssue(s(t,e)),a})),i=await Reflect.apply(h,this,n);return await e._def.returns._def.type.parseAsync(i,l).catch((e=>{throw a.addIssue(o(i,e)),a}))}))}{const e=this;return m((function(...t){const a=e._def.args.safeParse(t,l);if(!a.success)throw new r([s(t,a.error)]);const n=Reflect.apply(h,this,a.data),i=e._def.returns.safeParse(n,l);if(!i.success)throw new r([o(n,i.error)]);return i.data}))}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...e){return new se({...this._def,args:Q.create(e).rest(U.create())})}returns(e){return new se({...this._def,returns:e})}implement(e){return this.parse(e)}strictImplement(e){return this.parse(e)}static create(e,t,a){return new se({args:e||Q.create([]).rest(U.create()),returns:t||U.create(),typeName:ke.ZodFunction,...k(a)})}}class ne extends w{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})}}ne.create=(e,t)=>new ne({getter:e,typeName:ke.ZodLazy,...k(t)});class re extends w{_parse(e){if(e.data!==this._def.value){const t=this._getOrReturnCtx(e);return u(t,{received:t.data,code:n.invalid_literal,expected:this._def.value}),p}return{status:"valid",value:e.data}}get value(){return this._def.value}}function ie(e,t){return new oe({values:e,typeName:ke.ZodEnum,...k(t)})}re.create=(e,t)=>new re({value:e,typeName:ke.ZodLiteral,...k(t)});class oe extends w{_parse(t){if("string"!=typeof t.data){const a=this._getOrReturnCtx(t),s=this._def.values;return u(a,{expected:e.joinValues(s),received:a.parsedType,code:n.invalid_type}),p}if(-1===this._def.values.indexOf(t.data)){const e=this._getOrReturnCtx(t),a=this._def.values;return u(e,{received:e.data,code:n.invalid_enum_value,options:a}),p}return m(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){return oe.create(e)}exclude(e){return oe.create(this.options.filter((t=>!e.includes(t))))}}oe.create=ie;class de extends w{_parse(t){const s=e.getValidEnumValues(this._def.values),r=this._getOrReturnCtx(t);if(r.parsedType!==a.string&&r.parsedType!==a.number){const t=e.objectValues(s);return u(r,{expected:e.joinValues(t),received:r.parsedType,code:n.invalid_type}),p}if(-1===s.indexOf(t.data)){const t=e.objectValues(s);return u(r,{received:r.data,code:n.invalid_enum_value,options:t}),p}return m(t.data)}get enum(){return this._def.values}}de.create=(e,t)=>new de({values:e,typeName:ke.ZodNativeEnum,...k(t)});class ce extends w{unwrap(){return this._def.type}_parse(e){const{ctx:t}=this._processInputParams(e);if(t.parsedType!==a.promise&&!1===t.common.async)return u(t,{code:n.invalid_type,expected:a.promise,received:t.parsedType}),p;const s=t.parsedType===a.promise?t.data:Promise.resolve(t.data);return m(s.then((e=>this._def.type.parseAsync(e,{path:t.path,errorMap:t.common.contextualErrorMap}))))}}ce.create=(e,t)=>new ce({type:e,typeName:ke.ZodPromise,...k(t)});class ue extends w{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===ke.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(t){const{status:a,ctx:s}=this._processInputParams(t),n=this._def.effect||null,r={addIssue:e=>{u(s,e),e.fatal?a.abort():a.dirty()},get path(){return s.path}};if(r.addIssue=r.addIssue.bind(r),"preprocess"===n.type){const e=n.transform(s.data,r);return s.common.issues.length?{status:"dirty",value:s.data}:s.common.async?Promise.resolve(e).then((e=>this._def.schema._parseAsync({data:e,path:s.path,parent:s}))):this._def.schema._parseSync({data:e,path:s.path,parent:s})}if("refinement"===n.type){const e=e=>{const t=n.refinement(e,r);if(s.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===s.common.async){const t=this._def.schema._parseSync({data:s.data,path:s.path,parent:s});return"aborted"===t.status?p:("dirty"===t.status&&a.dirty(),e(t.value),{status:a.value,value:t.value})}return this._def.schema._parseAsync({data:s.data,path:s.path,parent:s}).then((t=>"aborted"===t.status?p:("dirty"===t.status&&a.dirty(),e(t.value).then((()=>({status:a.value,value:t.value}))))))}if("transform"===n.type){if(!1===s.common.async){const e=this._def.schema._parseSync({data:s.data,path:s.path,parent:s});if(!_(e))return e;const t=n.transform(e.value,r);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:s.data,path:s.path,parent:s}).then((e=>_(e)?Promise.resolve(n.transform(e.value,r)).then((e=>({status:a.value,value:e}))):e))}e.assertNever(n)}}ue.create=(e,t,a)=>new ue({schema:e,typeName:ke.ZodEffects,effect:t,...k(a)}),ue.createWithPreprocess=(e,t,a)=>new ue({schema:t,effect:{type:"preprocess",transform:e},typeName:ke.ZodEffects,...k(a)});class le extends w{_parse(e){return this._getType(e)===a.undefined?m(void 0):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}}le.create=(e,t)=>new le({innerType:e,typeName:ke.ZodOptional,...k(t)});class pe extends w{_parse(e){return this._getType(e)===a.null?m(null):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}}pe.create=(e,t)=>new pe({innerType:e,typeName:ke.ZodNullable,...k(t)});class he extends w{_parse(e){const{ctx:t}=this._processInputParams(e);let s=t.data;return t.parsedType===a.undefined&&(s=this._def.defaultValue()),this._def.innerType._parse({data:s,path:t.path,parent:t})}removeDefault(){return this._def.innerType}}he.create=(e,t)=>new he({innerType:e,typeName:ke.ZodDefault,defaultValue:"function"==typeof t.default?t.default:()=>t.default,...k(t)});class me extends w{_parse(e){const{ctx:t}=this._processInputParams(e),a={...t,common:{...t.common,issues:[]}},s=this._def.innerType._parse({data:a.data,path:a.path,parent:{...a}});return v(s)?s.then((e=>({status:"valid",value:"valid"===e.status?e.value:this._def.catchValue({get error(){return new r(a.common.issues)},input:a.data})}))):{status:"valid",value:"valid"===s.status?s.value:this._def.catchValue({get error(){return new r(a.common.issues)},input:a.data})}}removeCatch(){return this._def.innerType}}me.create=(e,t)=>new me({innerType:e,typeName:ke.ZodCatch,catchValue:"function"==typeof t.catch?t.catch:()=>t.catch,...k(t)});class fe extends w{_parse(e){if(this._getType(e)!==a.nan){const t=this._getOrReturnCtx(e);return u(t,{code:n.invalid_type,expected:a.nan,received:t.parsedType}),p}return{status:"valid",value:e.data}}}fe.create=e=>new fe({typeName:ke.ZodNaN,...k(e)});const ye=Symbol("zod_brand");class _e extends w{_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 ve extends w{_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?p:"dirty"===e.status?(t.dirty(),h(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?p:"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 ve({in:e,out:t,typeName:ke.ZodPipeline})}}class ge extends w{_parse(e){const t=this._def.innerType._parse(e);return _(t)&&(t.value=Object.freeze(t.value)),t}}ge.create=(e,t)=>new ge({innerType:e,typeName:ke.ZodReadonly,...k(t)});const xe=(e,t={},a)=>e?z.create().superRefine(((s,n)=>{var r,i;if(!e(s)){const e="function"==typeof t?t(s):"string"==typeof t?{message:t}:t,o=null===(i=null!==(r=e.fatal)&&void 0!==r?r:a)||void 0===i||i,d="string"==typeof e?{message:e}:e;n.addIssue({code:"custom",...d,fatal:o})}})):z.create(),be={object:W.lazycreate};var ke;!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"}(ke||(ke={}));const we=I.create,Ze=R.create,Te=fe.create,Oe=A.create,Ne=D.create,Ee=L.create,Se=$.create,Ce=M.create,je=V.create,Ie=z.create,Pe=U.create,Re=K.create,Ae=B.create,De=F.create,Le=W.create,$e=W.strictCreate,Me=H.create,Ve=Y.create,ze=X.create,Ue=Q.create,Ke=ee.create,Be=te.create,Fe=ae.create,qe=se.create,We=ne.create,He=re.create,Je=oe.create,Ye=de.create,Ge=ce.create,Xe=ue.create,Qe=le.create,et=pe.create,tt=ue.createWithPreprocess,at=ve.create,st={string:e=>I.create({...e,coerce:!0}),number:e=>R.create({...e,coerce:!0}),boolean:e=>D.create({...e,coerce:!0}),bigint:e=>A.create({...e,coerce:!0}),date:e=>L.create({...e,coerce:!0})},nt=p;var rt=Object.freeze({__proto__:null,defaultErrorMap:i,setErrorMap:function(e){o=e},getErrorMap:d,makeIssue:c,EMPTY_PATH:[],addIssueToContext:u,ParseStatus:l,INVALID:p,DIRTY:h,OK:m,isAborted:f,isDirty:y,isValid:_,isAsync:v,get util(){return e},get objectUtil(){return t},ZodParsedType:a,getParsedType:s,ZodType:w,ZodString:I,ZodNumber:R,ZodBigInt:A,ZodBoolean:D,ZodDate:L,ZodSymbol:$,ZodUndefined:M,ZodNull:V,ZodAny:z,ZodUnknown:U,ZodNever:K,ZodVoid:B,ZodArray:F,ZodObject:W,ZodUnion:H,ZodDiscriminatedUnion:Y,ZodIntersection:X,ZodTuple:Q,ZodRecord:ee,ZodMap:te,ZodSet:ae,ZodFunction:se,ZodLazy:ne,ZodLiteral:re,ZodEnum:oe,ZodNativeEnum:de,ZodPromise:ce,ZodEffects:ue,ZodTransformer:ue,ZodOptional:le,ZodNullable:pe,ZodDefault:he,ZodCatch:me,ZodNaN:fe,BRAND:ye,ZodBranded:_e,ZodPipeline:ve,ZodReadonly:ge,custom:xe,Schema:w,ZodSchema:w,late:be,get ZodFirstPartyTypeKind(){return ke},coerce:st,any:Ie,array:De,bigint:Oe,boolean:Ne,date:Ee,discriminatedUnion:Ve,effect:Xe,enum:Je,function:qe,instanceof:(e,t={message:`Input not instance of ${e.name}`})=>xe((t=>t instanceof e),t),intersection:ze,lazy:We,literal:He,map:Be,nan:Te,nativeEnum:Ye,never:Re,null:je,nullable:et,number:Ze,object:Le,oboolean:()=>Ne().optional(),onumber:()=>Ze().optional(),optional:Qe,ostring:()=>we().optional(),pipeline:at,preprocess:tt,promise:Ge,record:Ke,set:Fe,strictObject:$e,string:we,symbol:Se,transformer:Xe,tuple:Ue,undefined:Ce,union:Me,unknown:Pe,void:Ae,NEVER:nt,ZodIssueCode:n,quotelessJson:e=>JSON.stringify(e,null,2).replace(/"([^"]+)":/g,"$1:"),ZodError:r}),it=["interface","display","layout","module","panel","theme"],ot=["hook","endpoint"],dt=["operation"],ct=rt.object({app:rt.string(),api:rt.string()}),ut=rt.object({request:rt.optional(rt.object({urls:rt.array(rt.string()),methods:rt.array(rt.union([rt.literal("GET"),rt.literal("POST"),rt.literal("PATCH"),rt.literal("PUT"),rt.literal("DELETE")]))})),log:rt.optional(rt.object({})),sleep:rt.optional(rt.object({}))}),lt=rt.optional(rt.object({enabled:rt.boolean(),requestedScopes:ut})),pt=rt.union([rt.object({type:rt.enum(ot),name:rt.string(),source:rt.string()}),rt.object({type:rt.enum(it),name:rt.string(),source:rt.string()}),rt.object({type:rt.enum(dt),name:rt.string(),source:ct})]),ht=rt.object({host:rt.string(),hidden:rt.boolean().optional()}),mt=rt.object({type:rt.enum(it),path:rt.string(),source:rt.string()}),ft=rt.object({type:rt.enum(ot),path:rt.string(),source:rt.string(),sandbox:lt}),yt=rt.object({type:rt.enum(dt),path:ct,source:ct,sandbox:lt}),_t=rt.object({type:rt.literal("bundle"),partial:rt.boolean().optional(),path:ct,entries:rt.array(pt)});rt.array(pt);var vt=ht.and(rt.union([mt,ft,yt,_t]));function gt(e,t,a){return e in t?t[e]:a}rt.object({name:rt.string(),version:rt.string(),type:rt.union([rt.literal("module"),rt.literal("commonjs")]).optional(),description:rt.string().optional(),icon:rt.string().optional(),dependencies:rt.record(rt.string()).optional(),devDependencies:rt.record(rt.string()).optional(),"directus:extension":vt});var xt=({init:e},{env:t,logger:a})=>{const s=gt("BLOCKED_ENDPOINTS_ENABLED",t,!0),n=gt("BLOCKED_ENDPOINTS_PATHS",t,[]),r=gt("BLOCKED_ENDPOINTS_STATUS",t,418),i=gt("BLOCKED_ENDPOINTS_TYPE",t,"application/json"),o=gt("BLOCKED_ENDPOINTS_BODY",t,'{ "error": "Page blocked! I\'m a teapot now" }');return s?0===n.length?a.error('Environment variable "BLOCKED_ENDPOINTS_PATHS" needs to contain at least one path! try: /server/info'):void e("app.before",(({app:e})=>{n.forEach((e=>a.debug(`Blocking route "${e}"`))),e.get(n,((e,t)=>{t.set("Content-Type",i),t.status(r),t.send(o)}))})):a.warn("Block Endpoints extension is disabled")};export{xt as default}; 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "directus-extension-block-endpoints", 3 | "version": "1.0.6", 4 | "author": "brainslug", 5 | "keywords": [ 6 | "directus", 7 | "directus-extension", 8 | "directus-custom-hook" 9 | ], 10 | "type": "module", 11 | "directus:extension": { 12 | "type": "hook", 13 | "path": "dist/index.js", 14 | "source": "src/index.ts", 15 | "host": "^10.1.0" 16 | }, 17 | "scripts": { 18 | "build": "directus-extension build", 19 | "dev": "directus-extension build -w --no-minify" 20 | }, 21 | "devDependencies": { 22 | "@directus/extensions-sdk": "11.0.1", 23 | "@types/node": "^18.19.1", 24 | "typescript": "^5.4.2" 25 | }, 26 | "repository": { 27 | "type": "git", 28 | "url": "https://github.com/br41nslug/directus-extension-block-endpoints.git" 29 | }, 30 | "license": "MIT" 31 | } 32 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { defineHook } from '@directus/extensions-sdk'; 2 | 3 | function getEnv(variable: string, env: Record, fallback: T): T { 4 | if (!(variable in env)) return fallback; 5 | return env[variable] as T; 6 | } 7 | 8 | export default defineHook(({ init }: any, { env, logger }: any) => { 9 | const enabled = getEnv('BLOCKED_ENDPOINTS_ENABLED', env, true); 10 | const paths = getEnv('BLOCKED_ENDPOINTS_PATHS', env, []); 11 | const status = getEnv('BLOCKED_ENDPOINTS_STATUS', env, 418); 12 | const type = getEnv('BLOCKED_ENDPOINTS_TYPE', env, 'application/json'); 13 | const body = getEnv('BLOCKED_ENDPOINTS_BODY', env, '{ "error": "Page blocked! I\'m a teapot now" }'); 14 | if (!enabled) return logger.warn('Block Endpoints extension is disabled'); 15 | if (paths.length === 0) return logger.error('Environment variable "BLOCKED_ENDPOINTS_PATHS" needs to contain at least one path! try: /server/info'); 16 | init("app.before", ({ app }: any) => { 17 | paths.forEach(p => logger.debug(`Blocking route "${p}"`)); 18 | app.get(paths, (_req: any, res: any) => { 19 | res.set("Content-Type", type); 20 | res.status(status); 21 | res.send(body); 22 | }); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2019", 4 | "lib": ["ES2019", "DOM"], 5 | "moduleResolution": "node", 6 | "strict": true, 7 | "noFallthroughCasesInSwitch": true, 8 | "esModuleInterop": true, 9 | "noImplicitAny": true, 10 | "noImplicitThis": true, 11 | "noImplicitReturns": true, 12 | "noUnusedLocals": true, 13 | "noUncheckedIndexedAccess": true, 14 | "noUnusedParameters": true, 15 | "alwaysStrict": true, 16 | "strictNullChecks": true, 17 | "strictFunctionTypes": true, 18 | "strictBindCallApply": true, 19 | "strictPropertyInitialization": true, 20 | "resolveJsonModule": false, 21 | "skipLibCheck": true, 22 | "forceConsistentCasingInFileNames": true, 23 | "allowSyntheticDefaultImports": true, 24 | "isolatedModules": true, 25 | "rootDir": "./src", 26 | "sourceMap": true 27 | }, 28 | "include": ["./src/**/*.ts"] 29 | } 30 | --------------------------------------------------------------------------------