diff --git a/dist/browser.js b/dist/browser.js index 5c42f0e..0686439 100644 --- a/dist/browser.js +++ b/dist/browser.js @@ -1 +1,2 @@ -(()=>{var v=Object.defineProperty;var O=(o,n)=>{for(var r in n)v(o,r,{get:n[r],enumerable:!0})};var P={};O(P,{client:()=>A,formdata:()=>g,metroError:()=>f,request:()=>p,response:()=>S,symbols:()=>s,trace:()=>U,url:()=>b});var d="https://metro.muze.nl/details/",s={isProxy:Symbol("isProxy"),source:Symbol("source")},l=class o{#e={url:typeof window<"u"?window.location:"https://localhost"};#r=["get","post","put","delete","patch","head","options","query"];static tracers={};constructor(...n){for(let r of n)if(typeof r=="string"||r instanceof String)this.#e.url=""+r;else if(r instanceof o)Object.assign(this.#e,r.#e);else if(r instanceof Function)this.#t([r]);else if(r&&typeof r=="object")for(let e in r)e=="middlewares"?this.#t(r[e]):typeof r[e]=="function"?this.#e[e]=r[e](this.#e[e],this.#e):this.#e[e]=r[e];this.#e.verbs&&(this.#r=this.#e.verbs,delete this.#e.verbs);for(let r of this.#r)this[r]=async function(...e){return this.fetch(p(this.#e,...e,{method:r.toUpperCase()}))};Object.freeze(this)}#t(n){typeof n=="function"&&(n=[n]);let r=n.findIndex(e=>typeof e!="function");if(r>=0)throw f("metro.client: middlewares must be a function or an array of functions "+d+"client/invalid-middlewares-value/",n[r]);Array.isArray(this.#e.middlewares)||(this.#e.middlewares=[]),this.#e.middlewares=this.#e.middlewares.concat(n)}fetch(n,r){if(n=p(n,r),!n.url)throw f("metro.client."+n.method.toLowerCase()+": Missing url parameter "+d+"client/missing-url-param/",n);if(r||(r={}),typeof r!="object"||Array.isArray(r)||r instanceof String)throw f("metro.client.fetch: Options is not an object");let t=[async function(c){c[s.isProxy]&&(c=c[s.source]);let h=await fetch(c);return S(h)}].concat(this.#e?.middlewares?.slice()||[]);r=Object.assign({},this.#e,r);let a;for(let i of t)a=function(c,h){return async function(k){let m,x=Object.values(o.tracers);for(let u of x)u.request&&u.request.call(u,k,h);m=await h(k,c);for(let u of x)u.response&&u.response.call(u,m,h);return m}}(a,i);return a(n)}with(...n){return new o(this,...n)}};function A(...o){return new l(...o)}function w(o,n){let r=n.body;return r||(o===null?r=new ReadableStream:o instanceof ReadableStream?r=o:o instanceof Blob?r=o.stream():r=new ReadableStream({start(e){let t;switch(typeof o){case"object":if(typeof o.toString=="function")t=o.toString();else if(o instanceof FormData)t=new URLSearchParams(o).toString();else if(o instanceof ArrayBuffer||ArrayBuffer.isView(o))t=o;else throw f("Cannot convert body to ReadableStream",o);break;case"string":case"number":case"boolean":t=o;break;default:throw f("Cannot convert body to ReadableStream",o)}e.enqueue(t),e.close()}})),new Proxy(r,{get(e,t,a){switch(t){case s.isProxy:return!0;case s.source:return o;case"toString":return function(){return""+o}}if(typeof o=="object"&&t in o)return typeof o[t]=="function"?function(...i){return o[t].apply(o,i)}:o[t];if(t in e&&t!="toString")return typeof e[t]=="function"?function(...i){return e[t].apply(e,i)}:e[t]},has(e,t){return t in o},ownKeys(e){return Reflect.ownKeys(o)},getOwnPropertyDescriptor(e,t){return Object.getOwnPropertyDescriptor(o,t)}})}function L(o,n){let r=n||{};!r.url&&n.url&&(r.url=n.url);for(let e of["method","headers","body","mode","credentials","cache","redirect","referrer","referrerPolicy","integrity","keepalive","signal","priority","url"])if(typeof o[e]=="function")o[e](r[e],r);else if(typeof o[e]<"u")if(e=="url")r.url=b(r.url,o.url);else if(e=="headers"){r.headers=new Headers(n.headers),o.headers instanceof Headers||(o.headers=new Headers(o.headers));for(let[t,a]of o.headers.entries())r.headers.set(t,a)}else r[e]=o[e];return r}function p(...o){let n={url:typeof window<"u"?window.location:"https://localhost/",duplex:"half"};for(let t of o)typeof t=="string"||t instanceof URL||t instanceof URLSearchParams?n.url=b(n.url,t):t&&(t instanceof FormData||t instanceof ReadableStream||t instanceof Blob||t instanceof ArrayBuffer||t instanceof DataView)?n.body=t:t&&typeof t=="object"&&Object.assign(n,L(t,n));let r=n.body;r&&typeof r=="object"&&!(r instanceof String)&&!(r instanceof ReadableStream)&&!(r instanceof Blob)&&!(r instanceof ArrayBuffer)&&!(r instanceof DataView)&&!(r instanceof FormData)&&!(r instanceof URLSearchParams)&&(typeof TypedArray>"u"||!(r instanceof TypedArray))&&(n.body=JSON.stringify(r));let e=new Request(n.url,n);return Object.freeze(e),new Proxy(e,{get(t,a,i){switch(a){case s.source:return t;case s.isProxy:return!0;case"with":return function(...c){return r&&c.unshift({body:r}),p(t,...c)};case"toString":case"toJSON":return function(){return t[a].apply(t)};case"blob":case"text":case"json":return function(){return t[a].apply(t)};case"body":if(r||(r=t.body),r)return r[s.isProxy]?r:w(r,t);break}return t[a]}})}function R(o,n){let r=n||{};!r.url&&n.url&&(r.url=n.url);for(let e of["status","statusText","headers","body","url","type","redirected"])typeof o[e]=="function"?o[e](r[e],r):typeof o[e]<"u"&&(e=="url"?r.url=new URL(o.url,r.url||"https://localhost/"):r[e]=o[e]);return r}function S(...o){let n={};for(let e of o)typeof e=="string"?n.body=e:e instanceof Response?Object.assign(n,R(e,n)):e&&typeof e=="object"&&(e instanceof FormData||e instanceof Blob||e instanceof ArrayBuffer||e instanceof DataView||e instanceof ReadableStream||e instanceof URLSearchParams||e instanceof String||typeof TypedArray<"u"&&e instanceof TypedArray?n.body=e:Object.assign(n,R(e,n)));let r=new Response(n.body,n);return Object.freeze(r),new Proxy(r,{get(e,t,a){switch(t){case s.isProxy:return!0;case s.source:return e;case"with":return function(...i){return S(e,...i)};case"body":return n.body?n.body[s.isProxy]?n.body:w(n.body,e):w("",e);case"ok":return e.status>=200&&e.status<400;case"headers":return e.headers;default:if(t in n&&t!="toString")return n[t];if(t in e&&t!="toString")return typeof e[t]=="function"?function(...i){return e[t].apply(e,i)}:e[t];break}}})}function j(o,n){typeof n=="function"?n(o.searchParams,o):(n=new URLSearchParams(n),n.forEach((r,e)=>{o.searchParams.append(e,r)}))}function b(...o){let n=["hash","host","hostname","href","password","pathname","port","protocol","username","search","searchParams"],r=new URL("https://localhost/");for(let e of o)if(typeof e=="string"||e instanceof String)r=new URL(e,r);else if(e instanceof URL||typeof Location<"u"&&e instanceof Location)r=new URL(e);else if(e instanceof URLSearchParams)j(r,e);else if(e&&typeof e=="object")for(let t in e)if(t=="search")typeof e.search=="function"?e.search(r.search,r):r.search=new URLSearchParams(e.search);else if(t=="searchParams")j(r,e.searchParams);else{if(!n.includes(t))throw f("metro.url: unknown url parameter "+d+"url/unknown-param-name/",t);if(typeof e[t]=="function")e[t](r[t],r);else if(typeof e[t]=="string"||e[t]instanceof String||typeof e[t]=="number"||e[t]instanceof Number||typeof e[t]=="boolean"||e[t]instanceof Boolean)r[t]=""+e[t];else if(typeof e[t]=="object"&&e[t].toString)r[t]=e[t].toString();else throw f("metro.url: unsupported value for "+t+" "+d+"url/unsupported-param-value/",o[t])}else throw f("metro.url: unsupported option value "+d+"url/unsupported-option-value/",e);return Object.freeze(r),new Proxy(r,{get(e,t,a){switch(t){case s.isProxy:return!0;case s.source:return e;case"with":return function(...i){return b(e,...i)};case"toString":case"toJSON":return function(){return e[t]()}}return e[t]}})}function g(...o){var n=new FormData;for(let r of o)if(r instanceof FormData)for(let e of r.entries())n.append(e[0],e[1]);else if(r&&typeof r=="object")for(let e of Object.entries(r))if(Array.isArray(e[1]))for(let t of e[1])n.append(e[0],t);else n.append(e[0],e[1]);else throw new f("metro.formdata: unknown option type, only FormData or Object supported",r);return Object.freeze(n),new Proxy(n,{get:(r,e,t)=>{switch(e){case s.isProxy:return!0;case s.source:return r;case"with":return function(...a){return g(r,...a)};case"toString":case"toJSON":return function(){return r[e]()}}return r[e]}})}var y={error:(o,...n)=>{console.error("\u24C2\uFE0F ",o,...n)},info:(o,...n)=>{console.info("\u24C2\uFE0F ",o,...n)},group:o=>{console.group("\u24C2\uFE0F "+o)},groupEnd:o=>{console.groupEnd("\u24C2\uFE0F "+o)}};function f(o,...n){return y.error(o,...n),new Error(o,...n)}var U={add(o,n){l.tracers[o]=n},delete(o){delete l.tracers[o]},clear(){l.tracers={}},group(){let o=0;return{request:(n,r)=>{o++,y.group(o),y.info(n?.url,n,r)},response:(n,r)=>{y.info(n?.body?n.body[s.source]:null,n,r),y.groupEnd(o),o--}}}};window.metro=P;})(); +function e(e,t,r,o){Object.defineProperty(e,t,{get:r,set:o,enumerable:!0,configurable:!0})}var t=globalThis,r={},o={},n=t.parcelRequire94c2;null==n&&((n=function(e){if(e in r)return r[e].exports;if(e in o){var t=o[e];delete o[e];var n={id:e,exports:{}};return r[e]=n,t.call(n.exports,n,n.exports),n.exports}var s=Error("Cannot find module '"+e+"'");throw s.code="MODULE_NOT_FOUND",s}).register=function(e,t){o[e]=t},t.parcelRequire94c2=n),(0,n.register)("hkeot",function(t,r){e(t.exports,"symbols",()=>n),e(t.exports,"request",()=>c),e(t.exports,"metroError",()=>w),e(t.exports,"response",()=>u),e(t.exports,"client",()=>a),e(t.exports,"url",()=>p),e(t.exports,"formdata",()=>function e(...t){var r=new FormData;for(let e of t)if(e instanceof FormData)for(let t of e.entries())r.append(t[0],t[1]);else if(e&&"object"==typeof e)for(let t of Object.entries(e))if(Array.isArray(t[1]))for(let e of t[1])r.append(t[0],e);else r.append(t[0],t[1]);else throw new w("metro.formdata: unknown option type, only FormData or Object supported",e);return Object.freeze(r),new Proxy(r,{get:(t,r,o)=>{switch(r){case n.isProxy:return!0;case n.source:return t;case"with":return function(...r){return e(t,...r)}}return t[r]}})}),e(t.exports,"trace",()=>m);let o="https://metro.muze.nl/details/",n={isProxy:Symbol("isProxy"),source:Symbol("source")};class s{#e={url:"undefined"!=typeof window?window.location:"https://localhost"};#t=["get","post","put","delete","patch","head","options","query"];static tracers={};constructor(...e){for(let t of e)if("string"==typeof t||t instanceof String)this.#e.url=""+t;else if(t instanceof s)Object.assign(this.#e,t.#e);else if(t instanceof Function)this.#r([t]);else if(t&&"object"==typeof t)for(let e in t)"middlewares"==e?this.#r(t[e]):"function"==typeof t[e]?this.#e[e]=t[e](this.#e[e],this.#e):this.#e[e]=t[e];for(let e of(this.#e.verbs&&(this.#t=this.#e.verbs,delete this.#e.verbs),this.#t))this[e]=async function(...t){return this.fetch(c(this.#e,...t,{method:e.toUpperCase()}))};Object.freeze(this)}#r(e){"function"==typeof e&&(e=[e]);let t=e.findIndex(e=>"function"!=typeof e);if(t>=0)throw w("metro.client: middlewares must be a function or an array of functions "+o+"client/invalid-middlewares-value/",e[t]);Array.isArray(this.#e.middlewares)||(this.#e.middlewares=[]),this.#e.middlewares=this.#e.middlewares.concat(e)}fetch(e,t){let r;if(!(e=c(e,t)).url)throw w("metro.client."+e.method.toLowerCase()+": Missing url parameter "+o+"client/missing-url-param/",e);if(t||(t={}),"object"!=typeof t||Array.isArray(t)||t instanceof String)throw w("metro.client.fetch: Options is not an object");let a=[async function(e){return e[n.isProxy]&&(e=e[n.source]),u(await fetch(e))}].concat(this.#e?.middlewares?.slice()||[]);for(let e of(t=Object.assign({},this.#e,t),a))r=function(e,t){return async function(r){let o;let n=Object.values(s.tracers);for(let e of n)e.request&&e.request.call(e,r,t);for(let s of(o=await t(r,e),n))s.response&&s.response.call(s,o,t);return o}}(r,e);return r(e)}with(...e){return new s(this,...e)}}function a(...e){return new s(...e)}function i(e,t){let r=t.body;return r||(null===e?r=new ReadableStream:e instanceof ReadableStream?r=e:e instanceof Blob?r=e.stream():r=new ReadableStream({start(t){let r;switch(typeof e){case"object":if("function"==typeof e.toString)r=e.toString();else if(e instanceof FormData)r=new URLSearchParams(e).toString();else if(e instanceof ArrayBuffer||ArrayBuffer.isView(e))r=e;else throw w("Cannot convert body to ReadableStream",e);break;case"string":case"number":case"boolean":r=e;break;default:throw w("Cannot convert body to ReadableStream",e)}t.enqueue(r),t.close()}})),new Proxy(r,{get(t,r,o){switch(r){case n.isProxy:return!0;case n.source:return e;case"toString":return function(){return""+e}}return"object"==typeof e&&r in e?"function"==typeof e[r]?function(...t){return e[r].apply(e,t)}:e[r]:r in t&&"toString"!=r?"function"==typeof t[r]?function(...e){return t[r].apply(t,e)}:t[r]:void 0},has:(t,r)=>r in e,ownKeys:t=>Reflect.ownKeys(e),getOwnPropertyDescriptor:(t,r)=>Object.getOwnPropertyDescriptor(e,r)})}function c(...e){let t={url:"undefined"!=typeof window?window.location:"https://localhost/",duplex:"half"};for(let r of e)"string"==typeof r||r instanceof URL||r instanceof URLSearchParams?t.url=p(t.url,r):r&&(r instanceof FormData||r instanceof ReadableStream||r instanceof Blob||r instanceof ArrayBuffer||r instanceof DataView)?t.body=r:r&&"object"==typeof r&&Object.assign(t,function(e,t){let r=t||{};for(let o of(!r.url&&t.url&&(r.url=t.url),["method","headers","body","mode","credentials","cache","redirect","referrer","referrerPolicy","integrity","keepalive","signal","priority","url"]))if("function"==typeof e[o])e[o](r[o],r);else if(void 0!==e[o]){if("url"==o)r.url=p(r.url,e.url);else if("headers"==o)for(let[o,n]of(r.headers=new Headers(t.headers),e.headers instanceof Headers||(e.headers=new Headers(e.headers)),e.headers.entries()))r.headers.set(o,n);else r[o]=e[o]}return r}(r,t));let r=t.body;!r||"object"!=typeof r||r instanceof String||r instanceof ReadableStream||r instanceof Blob||r instanceof ArrayBuffer||r instanceof DataView||r instanceof FormData||r instanceof URLSearchParams||"undefined"!=typeof TypedArray&&r instanceof TypedArray||(t.body=JSON.stringify(r));let o=new Request(t.url,t);return Object.freeze(o),new Proxy(o,{get(e,t,o){switch(t){case n.source:return e;case n.isProxy:return!0;case"with":return function(...t){return r&&t.unshift({body:r}),c(e,...t)};case"toString":case"toJSON":return function(){return e[t].apply(e)};case"blob":case"text":case"json":return function(){return e[t].apply(e)};case"body":if(r||(r=e.body),r){if(r[n.isProxy])return r;return i(r,e)}}return e[t]}})}function f(e,t){let r=t||{};for(let o of(!r.url&&t.url&&(r.url=t.url),["status","statusText","headers","body","url","type","redirected"]))"function"==typeof e[o]?e[o](r[o],r):void 0!==e[o]&&("url"==o?r.url=new URL(e.url,r.url||"https://localhost/"):r[o]=e[o]);return r}function u(...e){let t={};for(let r of e)"string"==typeof r?t.body=r:r instanceof Response?Object.assign(t,f(r,t)):r&&"object"==typeof r&&(r instanceof FormData||r instanceof Blob||r instanceof ArrayBuffer||r instanceof DataView||r instanceof ReadableStream||r instanceof URLSearchParams||r instanceof String||"undefined"!=typeof TypedArray&&r instanceof TypedArray?t.body=r:Object.assign(t,f(r,t)));let r=new Response(t.body,t);return Object.freeze(r),new Proxy(r,{get(e,r,o){switch(r){case n.isProxy:return!0;case n.source:return e;case"with":return function(...t){return u(e,...t)};case"body":if(!t.body)return i("",e);if(t.body[n.isProxy])return t.body;return i(t.body,e);case"ok":return e.status>=200&&e.status<400;case"headers":return e.headers;default:if(r in t&&"toString"!=r)return t[r];if(r in e&&"toString"!=r){if("function"==typeof e[r])return function(...t){return e[r].apply(e,t)};return e[r]}}}})}function l(e,t){"function"==typeof t?t(e.searchParams,e):(t=new URLSearchParams(t)).forEach((t,r)=>{e.searchParams.append(r,t)})}function p(...e){let t=["hash","host","hostname","href","password","pathname","port","protocol","username","search","searchParams"],r=new URL("https://localhost/");for(let n of e)if("string"==typeof n||n instanceof String)r=new URL(n,r);else if(n instanceof URL||"undefined"!=typeof Location&&n instanceof Location)r=new URL(n);else if(n instanceof URLSearchParams)l(r,n);else if(n&&"object"==typeof n)for(let s in n)if("search"==s)"function"==typeof n.search?n.search(r.search,r):r.search=new URLSearchParams(n.search);else if("searchParams"==s)l(r,n.searchParams);else{if(!t.includes(s))throw w("metro.url: unknown url parameter "+o+"url/unknown-param-name/",s);if("function"==typeof n[s])n[s](r[s],r);else if("string"==typeof n[s]||n[s]instanceof String||"number"==typeof n[s]||n[s]instanceof Number||"boolean"==typeof n[s]||n[s]instanceof Boolean)r[s]=""+n[s];else if("object"==typeof n[s]&&n[s].toString)r[s]=n[s].toString();else throw w("metro.url: unsupported value for "+s+" "+o+"url/unsupported-param-value/",e[s])}else throw w("metro.url: unsupported option value "+o+"url/unsupported-option-value/",n);return Object.freeze(r),new Proxy(r,{get(e,t,r){switch(t){case n.isProxy:return!0;case n.source:return e;case"with":return function(...t){return p(e,...t)};case"toString":case"toJSON":return function(){return e[t]()}}return e[t]}})}let d=(e,...t)=>{console.error("Ⓜ️ ",e,...t)},y=(e,...t)=>{console.info("Ⓜ️ ",e,...t)},h=e=>{console.group("Ⓜ️ "+e)},b=e=>{console.groupEnd("Ⓜ️ "+e)};function w(e,...t){return d(e,...t),Error(e,...t)}let m={add(e,t){s.tracers[e]=t},delete(e){delete s.tracers[e]},clear(){s.tracers={}},group(){let e=0;return{request:(t,r)=>{h(++e),y(t?.url,t,r)},response:(t,r)=>{y(t?.body?t.body[n.source]:null,t,r),b(e),e--}}}}});var s=n("hkeot");window.metro=s; +//# sourceMappingURL=browser.js.map diff --git a/dist/browser.js.map b/dist/browser.js.map index f7e5c6f..dbb9627 100644 --- a/dist/browser.js.map +++ b/dist/browser.js.map @@ -1 +1 @@ -{"mappings":"A,S,E,C,C,C,C,C,C,C,E,O,c,C,E,E,C,I,E,I,E,W,C,E,a,C,C,E,C,I,E,W,E,C,E,E,C,E,E,E,iB,A,O,I,A,C,E,S,C,E,G,K,E,O,C,C,E,C,O,C,G,K,E,C,I,E,C,C,E,A,Q,C,C,E,C,I,E,C,G,E,Q,C,C,E,O,C,C,E,C,E,E,I,C,E,O,C,E,E,O,E,E,O,A,C,I,E,A,M,uB,E,I,O,E,I,C,mB,C,C,E,Q,C,S,C,C,C,E,C,C,E,C,C,E,E,iB,C,G,A,C,E,E,Q,A,E,Q,S,C,C,C,E,E,E,O,C,U,I,G,E,E,O,C,U,I,G,E,E,O,C,a,I,G,E,E,O,C,W,I,G,E,E,O,C,S,I,G,E,E,O,C,M,I,G,E,E,O,C,W,ICipBO,SAAS,EAAS,GAAG,CAAO,EAElC,IAAI,EAAS,IAAI,SACjB,IAAK,IAAI,KAAU,EAClB,GAAI,aAAkB,SACrB,IAAK,IAAI,KAAS,EAAO,OAAO,GAC/B,EAAO,MAAM,CAAC,CAAK,CAAC,EAAE,CAAC,CAAK,CAAC,EAAE,OAE1B,GAAI,GAAU,AAAiB,UAAjB,OAAO,EAC3B,IAAK,IAAI,KAAS,OAAO,OAAO,CAAC,GAChC,GAAI,MAAM,OAAO,CAAC,CAAK,CAAC,EAAE,EACzB,IAAK,IAAI,KAAS,CAAK,CAAC,EAAE,CACzB,EAAO,MAAM,CAAC,CAAK,CAAC,EAAE,CAAE,QAGzB,EAAO,MAAM,CAAC,CAAK,CAAC,EAAE,CAAC,CAAK,CAAC,EAAE,OAIjC,MAAM,IAAI,EAAW,yEAAyE,GAIhG,OADA,OAAO,MAAM,CAAC,GACP,IAAI,MAAM,EAAQ,CACxB,IAAK,CAAC,EAAO,EAAK,KACjB,OAAO,GACN,KAAK,EAAQ,OAAO,CACnB,MAAO,CAAA,CAER,MAAK,EAAQ,MAAM,CAClB,OAAO,CAER,KAAK,OACJ,OAAO,SAAS,GAAG,CAAO,EACzB,OAAO,EAAS,KAAW,EAC5B,CAED,KAAK,WACL,IAAK,SACJ,OAAO,WACN,OAAO,CAAM,CAAC,EAAK,EACpB,CAEF,CACA,OAAO,CAAM,CAAC,EAAK,AACpB,CACD,EACD,G,E,E,O,C,Q,I,GA7rBA,IAAM,EAAW,iCAOJ,EAAU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","sources":["","src/metro.mjs","src/browser.mjs"],"sourcesContent":["\nfunction $parcel$export(e, n, v, s) {\n Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});\n}\n\n var $parcel$global = globalThis;\n \nvar $parcel$modules = {};\nvar $parcel$inits = {};\n\nvar parcelRequire = $parcel$global[\"parcelRequireea2c\"];\n\nif (parcelRequire == null) {\n parcelRequire = function(id) {\n if (id in $parcel$modules) {\n return $parcel$modules[id].exports;\n }\n if (id in $parcel$inits) {\n var init = $parcel$inits[id];\n delete $parcel$inits[id];\n var module = {id: id, exports: {}};\n $parcel$modules[id] = module;\n init.call(module.exports, module, module.exports);\n return module.exports;\n }\n var err = new Error(\"Cannot find module '\" + id + \"'\");\n err.code = 'MODULE_NOT_FOUND';\n throw err;\n };\n\n parcelRequire.register = function register(id, init) {\n $parcel$inits[id] = init;\n };\n\n $parcel$global[\"parcelRequireea2c\"] = parcelRequire;\n}\n\nvar parcelRegister = parcelRequire.register;\nparcelRegister(\"hkeot\", function(module, exports) {\n\n$parcel$export(module.exports, \"symbols\", () => $86c8ab3a59b0bae1$export$47616e9f7f5fe113);\n$parcel$export(module.exports, \"request\", () => $86c8ab3a59b0bae1$export$b5fe3f66a567bec0);\n$parcel$export(module.exports, \"metroError\", () => $86c8ab3a59b0bae1$export$7079e2c78c274c66);\n$parcel$export(module.exports, \"response\", () => $86c8ab3a59b0bae1$export$785bb8ef7fad1f74);\n$parcel$export(module.exports, \"client\", () => $86c8ab3a59b0bae1$export$388e0302ca0d9a41);\n$parcel$export(module.exports, \"url\", () => $86c8ab3a59b0bae1$export$128fa18b7194ef);\n$parcel$export(module.exports, \"formdata\", () => $86c8ab3a59b0bae1$export$5de500aade6bf050);\n$parcel$export(module.exports, \"trace\", () => $86c8ab3a59b0bae1$export$357889f174732d38);\n/**\n * base URL used to link to more information about an error message\n */ const $86c8ab3a59b0bae1$var$metroURL = \"https://metro.muze.nl/details/\";\nconst $86c8ab3a59b0bae1$export$47616e9f7f5fe113 = {\n isProxy: Symbol(\"isProxy\"),\n source: Symbol(\"source\")\n};\n/**\n * Metro HTTP Client with middleware support\n * @method get\n * @method post\n * @method put\n * @method delete\n * @method patch\n * @method head\n * @method options\n * @method query\n */ class $86c8ab3a59b0bae1$var$Client {\n #options = {\n url: typeof window != \"undefined\" ? window.location : \"https://localhost\"\n };\n #verbs = [\n \"get\",\n \"post\",\n \"put\",\n \"delete\",\n \"patch\",\n \"head\",\n \"options\",\n \"query\"\n ];\n static tracers = {};\n /**\n\t * @typedef {Object} ClientOptions\n\t * @property {Array} middlewares - list of middleware functions\n\t * @property {string|URL} url - default url of the client\n\t * @property {[string]} verbs - a list of verb methods to expose, e.g. ['get','post']\n\t * \n\t * Constructs a new metro client. Can have any number of params.\n\t * @params {ClientOptions|URL|Function|Client}\n\t * @returns {Client} - A metro client object with given or default verb methods\n\t */ constructor(...options){\n for (let option of options){\n if (typeof option == \"string\" || option instanceof String) this.#options.url = \"\" + option;\n else if (option instanceof $86c8ab3a59b0bae1$var$Client) Object.assign(this.#options, option.#options);\n else if (option instanceof Function) this.#addMiddlewares([\n option\n ]);\n else if (option && typeof option == \"object\") for(let param in option){\n if (param == \"middlewares\") this.#addMiddlewares(option[param]);\n else if (typeof option[param] == \"function\") this.#options[param] = option[param](this.#options[param], this.#options);\n else this.#options[param] = option[param];\n }\n }\n if (this.#options.verbs) {\n this.#verbs = this.#options.verbs;\n delete this.#options.verbs;\n }\n for (const verb of this.#verbs)this[verb] = async function(...options) {\n return this.fetch($86c8ab3a59b0bae1$export$b5fe3f66a567bec0(this.#options, ...options, {\n method: verb.toUpperCase()\n }));\n };\n Object.freeze(this);\n }\n #addMiddlewares(middlewares) {\n if (typeof middlewares == \"function\") middlewares = [\n middlewares\n ];\n let index = middlewares.findIndex((m)=>typeof m != \"function\");\n if (index >= 0) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"metro.client: middlewares must be a function or an array of functions \" + $86c8ab3a59b0bae1$var$metroURL + \"client/invalid-middlewares-value/\", middlewares[index]);\n if (!Array.isArray(this.#options.middlewares)) this.#options.middlewares = [];\n this.#options.middlewares = this.#options.middlewares.concat(middlewares);\n }\n /**\n\t * Mimics the standard browser fetch method, but uses any middleware installed through\n\t * the constructor.\n\t * @param {Request|string|Object} - Required. The URL or Request object, accepts all types that are accepted by metro.request\n\t * @param {Object} - Optional. Any object that is accepted by metro.request\n\t * @return {Promise} - The metro.response to this request, or any other result as changed by any included middleware.\n\t */ fetch(req, options) {\n req = $86c8ab3a59b0bae1$export$b5fe3f66a567bec0(req, options);\n if (!req.url) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"metro.client.\" + req.method.toLowerCase() + \": Missing url parameter \" + $86c8ab3a59b0bae1$var$metroURL + \"client/missing-url-param/\", req);\n if (!options) options = {};\n if (!(typeof options === \"object\") || Array.isArray(options) || options instanceof String) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"metro.client.fetch: Options is not an object\");\n const metrofetch = async function browserFetch(req) {\n if (req[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy]) // even though a Proxy is supposed to be 'invisible'\n // fetch() doesn't work with the proxy (in Firefox), \n // you need the actual Request object here\n req = req[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.source];\n const res = await fetch(req);\n return $86c8ab3a59b0bae1$export$785bb8ef7fad1f74(res);\n };\n let middlewares = [\n metrofetch\n ].concat(this.#options?.middlewares?.slice() || []);\n options = Object.assign({}, this.#options, options);\n //@TODO: do this once in constructor?\n let next;\n for (let middleware of middlewares)next = function(next, middleware) {\n return async function(req) {\n let res;\n let tracers = Object.values($86c8ab3a59b0bae1$var$Client.tracers);\n for (let tracer of tracers)if (tracer.request) tracer.request.call(tracer, req, middleware);\n res = await middleware(req, next);\n for (let tracer of tracers)if (tracer.response) tracer.response.call(tracer, res, middleware);\n return res;\n };\n }(next, middleware);\n return next(req);\n }\n with(...options) {\n return new $86c8ab3a59b0bae1$var$Client(this, ...options);\n }\n}\nfunction $86c8ab3a59b0bae1$export$388e0302ca0d9a41(...options) {\n return new $86c8ab3a59b0bae1$var$Client(...options);\n}\nfunction $86c8ab3a59b0bae1$var$appendHeaders(r, headers) {\n if (!Array.isArray(headers)) headers = [\n headers\n ];\n headers.forEach((header)=>{\n if (typeof header == \"function\") {\n let result = header(r.headers, r);\n if (result) {\n if (!Array.isArray(result)) result = [\n result\n ];\n headers = headers.concat(result);\n }\n }\n });\n headers.forEach((header)=>{\n Object.entries(header).forEach(([name, value])=>{\n r.headers.append(name, value);\n });\n });\n}\nfunction $86c8ab3a59b0bae1$var$bodyProxy(body, r) {\n let source = r.body;\n if (!source) {\n //Firefox does not allow access to Request.body (undefined)\n //Chrome and Nodejs do, so mimic the correct (documented)\n //result here\n if (body === null) source = new ReadableStream();\n else if (body instanceof ReadableStream) source = body;\n else if (body instanceof Blob) source = body.stream();\n else source = new ReadableStream({\n start (controller) {\n let chunk;\n switch(typeof body){\n case \"object\":\n if (typeof body.toString == \"function\") // also catches URLSearchParams\n chunk = body.toString();\n else if (body instanceof FormData) chunk = new URLSearchParams(body).toString();\n else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) // catchs TypedArrays - e.g. Uint16Array\n chunk = body;\n else throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"Cannot convert body to ReadableStream\", body);\n break;\n case \"string\":\n case \"number\":\n case \"boolean\":\n chunk = body;\n break;\n default:\n throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"Cannot convert body to ReadableStream\", body);\n }\n controller.enqueue(chunk);\n controller.close();\n }\n });\n }\n return new Proxy(source, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return body;\n case \"toString\":\n return function() {\n return \"\" + body;\n };\n }\n if (typeof body == \"object\") {\n if (prop in body) {\n if (typeof body[prop] == \"function\") return function(...args) {\n return body[prop].apply(body, args);\n };\n return body[prop];\n }\n }\n if (prop in target && prop != \"toString\") {\n // skipped toString, since it has no usable output\n // and body may have its own toString\n if (typeof target[prop] == \"function\") return function(...args) {\n return target[prop].apply(target, args);\n };\n return target[prop];\n }\n },\n has (target, prop) {\n return prop in body;\n },\n ownKeys (target) {\n return Reflect.ownKeys(body);\n },\n getOwnPropertyDescriptor (target, prop) {\n return Object.getOwnPropertyDescriptor(body, prop);\n }\n });\n}\nfunction $86c8ab3a59b0bae1$var$getRequestParams(req, current) {\n let params = current || {};\n if (!params.url && current.url) params.url = current.url;\n // function to fetch all relevant properties of a Request\n for (let prop of [\n \"method\",\n \"headers\",\n \"body\",\n \"mode\",\n \"credentials\",\n \"cache\",\n \"redirect\",\n \"referrer\",\n \"referrerPolicy\",\n \"integrity\",\n \"keepalive\",\n \"signal\",\n \"priority\",\n \"url\"\n ]){\n if (typeof req[prop] == \"function\") req[prop](params[prop], params);\n else if (typeof req[prop] != \"undefined\") {\n if (prop == \"url\") params.url = $86c8ab3a59b0bae1$export$128fa18b7194ef(params.url, req.url);\n else if (prop == \"headers\") {\n params.headers = new Headers(current.headers);\n if (!(req.headers instanceof Headers)) req.headers = new Headers(req.headers);\n for (let [key, value] of req.headers.entries())params.headers.set(key, value);\n } else params[prop] = req[prop];\n }\n }\n return params;\n}\nfunction $86c8ab3a59b0bae1$export$b5fe3f66a567bec0(...options) {\n // the standard Request constructor is a minefield\n // so first gather all the options together into a single\n // javascript object, then set it in one go\n let requestParams = {\n url: typeof window != \"undefined\" ? window.location : \"https://localhost/\",\n duplex: \"half\" // required when setting body to ReadableStream, just set it here by default already\n };\n for (let option of options){\n if (typeof option == \"string\" || option instanceof URL || option instanceof URLSearchParams) requestParams.url = $86c8ab3a59b0bae1$export$128fa18b7194ef(requestParams.url, option);\n else if (option && (option instanceof FormData || option instanceof ReadableStream || option instanceof Blob || option instanceof ArrayBuffer || option instanceof DataView)) requestParams.body = option;\n else if (option && typeof option == \"object\") Object.assign(requestParams, $86c8ab3a59b0bae1$var$getRequestParams(option, requestParams));\n }\n let body = requestParams.body;\n if (body) {\n if (typeof body == \"object\" && !(body instanceof String) && !(body instanceof ReadableStream) && !(body instanceof Blob) && !(body instanceof ArrayBuffer) && !(body instanceof DataView) && !(body instanceof FormData) && !(body instanceof URLSearchParams) && (typeof TypedArray == \"undefined\" || !(body instanceof TypedArray))) requestParams.body = JSON.stringify(body);\n }\n let r = new Request(requestParams.url, requestParams);\n Object.freeze(r);\n return new Proxy(r, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case \"with\":\n return function(...options) {\n if (body) options.unshift({\n body: body\n }) // unshifted so it can be overridden by options\n ;\n return $86c8ab3a59b0bae1$export$b5fe3f66a567bec0(target, ...options);\n };\n case \"toString\":\n case \"toJSON\":\n return function() {\n return target[prop].apply(target);\n };\n case \"blob\":\n case \"text\":\n case \"json\":\n return function() {\n return target[prop].apply(target);\n };\n case \"body\":\n // Request.body is always a ReadableStream\n // which is a horrible API, if you want to\n // allow middleware to alter the body\n // so we keep the original body, wrap a Proxy\n // around it to keep the ReadableStream api\n // accessible, but allow access to the original\n // body value as well\n if (!body) body = target.body;\n if (body) {\n if (body[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy]) return body;\n return $86c8ab3a59b0bae1$var$bodyProxy(body, target);\n }\n break;\n }\n return target[prop];\n }\n });\n}\nfunction $86c8ab3a59b0bae1$var$getResponseParams(res, current) {\n // function to fetch all relevant properties of a Response\n let params = current || {};\n if (!params.url && current.url) params.url = current.url;\n for (let prop of [\n \"status\",\n \"statusText\",\n \"headers\",\n \"body\",\n \"url\",\n \"type\",\n \"redirected\"\n ]){\n if (typeof res[prop] == \"function\") res[prop](params[prop], params);\n else if (typeof res[prop] != \"undefined\") {\n if (prop == \"url\") params.url = new URL(res.url, params.url || \"https://localhost/\");\n else params[prop] = res[prop];\n }\n }\n return params;\n}\nfunction $86c8ab3a59b0bae1$export$785bb8ef7fad1f74(...options) {\n let responseParams = {};\n for (let option of options){\n if (typeof option == \"string\") responseParams.body = option;\n else if (option instanceof Response) Object.assign(responseParams, $86c8ab3a59b0bae1$var$getResponseParams(option, responseParams));\n else if (option && typeof option == \"object\") {\n if (option instanceof FormData || option instanceof Blob || option instanceof ArrayBuffer || option instanceof DataView || option instanceof ReadableStream || option instanceof URLSearchParams || option instanceof String || typeof TypedArray != \"undefined\" && option instanceof TypedArray) responseParams.body = option;\n else Object.assign(responseParams, $86c8ab3a59b0bae1$var$getResponseParams(option, responseParams));\n }\n }\n let r = new Response(responseParams.body, responseParams);\n Object.freeze(r);\n return new Proxy(r, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case \"with\":\n return function(...options) {\n return $86c8ab3a59b0bae1$export$785bb8ef7fad1f74(target, ...options);\n };\n case \"body\":\n if (responseParams.body) {\n if (responseParams.body[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy]) return responseParams.body;\n return $86c8ab3a59b0bae1$var$bodyProxy(responseParams.body, target);\n } else return $86c8ab3a59b0bae1$var$bodyProxy(\"\", target);\n break;\n case \"ok\":\n return target.status >= 200 && target.status < 400;\n case \"headers\":\n return target.headers;\n default:\n if (prop in responseParams && prop != \"toString\") return responseParams[prop];\n if (prop in target && prop != \"toString\") {\n // skipped toString, since it has no usable output\n // and body may have its own toString\n if (typeof target[prop] == \"function\") return function(...args) {\n return target[prop].apply(target, args);\n };\n return target[prop];\n }\n break;\n }\n return undefined;\n }\n });\n}\nfunction $86c8ab3a59b0bae1$var$appendSearchParams(url, params) {\n if (typeof params == \"function\") params(url.searchParams, url);\n else {\n params = new URLSearchParams(params);\n params.forEach((value, key)=>{\n url.searchParams.append(key, value);\n });\n }\n}\nfunction $86c8ab3a59b0bae1$export$128fa18b7194ef(...options) {\n let validParams = [\n \"hash\",\n \"host\",\n \"hostname\",\n \"href\",\n \"password\",\n \"pathname\",\n \"port\",\n \"protocol\",\n \"username\",\n \"search\",\n \"searchParams\"\n ];\n let u = new URL(\"https://localhost/\");\n for (let option of options){\n if (typeof option == \"string\" || option instanceof String) // option is a relative or absolute url\n u = new URL(option, u);\n else if (option instanceof URL || typeof Location != \"undefined\" && option instanceof Location) u = new URL(option);\n else if (option instanceof URLSearchParams) $86c8ab3a59b0bae1$var$appendSearchParams(u, option);\n else if (option && typeof option == \"object\") for(let param in option){\n if (param == \"search\") {\n if (typeof option.search == \"function\") option.search(u.search, u);\n else u.search = new URLSearchParams(option.search);\n } else if (param == \"searchParams\") $86c8ab3a59b0bae1$var$appendSearchParams(u, option.searchParams);\n else {\n if (!validParams.includes(param)) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"metro.url: unknown url parameter \" + $86c8ab3a59b0bae1$var$metroURL + \"url/unknown-param-name/\", param);\n if (typeof option[param] == \"function\") option[param](u[param], u);\n else if (typeof option[param] == \"string\" || option[param] instanceof String || typeof option[param] == \"number\" || option[param] instanceof Number || typeof option[param] == \"boolean\" || option[param] instanceof Boolean) u[param] = \"\" + option[param];\n else if (typeof option[param] == \"object\" && option[param].toString) u[param] = option[param].toString();\n else throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"metro.url: unsupported value for \" + param + \" \" + $86c8ab3a59b0bae1$var$metroURL + \"url/unsupported-param-value/\", options[param]);\n }\n }\n else throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"metro.url: unsupported option value \" + $86c8ab3a59b0bae1$var$metroURL + \"url/unsupported-option-value/\", option);\n }\n Object.freeze(u);\n return new Proxy(u, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case \"with\":\n return function(...options) {\n return $86c8ab3a59b0bae1$export$128fa18b7194ef(target, ...options);\n };\n case \"toString\":\n case \"toJSON\":\n return function() {\n return target[prop]();\n };\n }\n return target[prop];\n }\n });\n}\nfunction $86c8ab3a59b0bae1$export$5de500aade6bf050(...options) {\n var params = new FormData();\n for (let option of options){\n if (option instanceof FormData) for (let entry of option.entries())params.append(entry[0], entry[1]);\n else if (option && typeof option == \"object\") for (let entry of Object.entries(option)){\n if (Array.isArray(entry[1])) for (let value of entry[1])params.append(entry[0], value);\n else params.append(entry[0], entry[1]);\n }\n else throw new $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"metro.formdata: unknown option type, only FormData or Object supported\", option);\n }\n Object.freeze(params);\n return new Proxy(params, {\n get: (target, prop, receiver)=>{\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case \"with\":\n return function(...options) {\n return $86c8ab3a59b0bae1$export$5de500aade6bf050(target, ...options);\n };\n case \"toString\":\n case \"toJSON\":\n return function() {\n return target[prop]();\n };\n }\n return target[prop];\n }\n });\n}\nconst $86c8ab3a59b0bae1$var$metroConsole = {\n error: (message, ...details)=>{\n console.error(\"\\u24C2\\uFE0F \", message, ...details);\n },\n info: (message, ...details)=>{\n console.info(\"\\u24C2\\uFE0F \", message, ...details);\n },\n group: (name)=>{\n console.group(\"\\u24C2\\uFE0F \" + name);\n },\n groupEnd: (name)=>{\n console.groupEnd(\"\\u24C2\\uFE0F \" + name);\n }\n};\nfunction $86c8ab3a59b0bae1$export$7079e2c78c274c66(message, ...details) {\n $86c8ab3a59b0bae1$var$metroConsole.error(message, ...details);\n return new Error(message, ...details);\n}\nconst $86c8ab3a59b0bae1$export$357889f174732d38 = {\n /**\n\t * Adds a named tracer function\n\t * @param {string} name - the name of the tracer\n\t * @param {Function} tracer - the tracer function to call\n\t */ add (name, tracer) {\n $86c8ab3a59b0bae1$var$Client.tracers[name] = tracer;\n },\n /**\n\t * Removes a named tracer function\n\t * @param {string} name\n\t */ delete (name) {\n delete $86c8ab3a59b0bae1$var$Client.tracers[name];\n },\n /**\n\t * Removes all tracer functions\n\t */ clear () {\n $86c8ab3a59b0bae1$var$Client.tracers = {};\n },\n /**\n\t * Returns a set of request and response tracer functions that use the\n\t * console.group feature to shows nested request/response pairs, with\n\t * most commonly needed information for debugging\n\t */ group () {\n let group = 0;\n return {\n request: (req, middleware)=>{\n group++;\n $86c8ab3a59b0bae1$var$metroConsole.group(group);\n $86c8ab3a59b0bae1$var$metroConsole.info(req?.url, req, middleware);\n },\n response: (res, middleware)=>{\n $86c8ab3a59b0bae1$var$metroConsole.info(res?.body ? res.body[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.source] : null, res, middleware);\n $86c8ab3a59b0bae1$var$metroConsole.groupEnd(group);\n group--;\n }\n };\n }\n};\n\n});\n\n\nvar $hkeot = parcelRequire(\"hkeot\");\nwindow.metro = $hkeot;\n\n\n//# sourceMappingURL=browser.js.map\n","/**\n * base URL used to link to more information about an error message\n */\nconst metroURL = 'https://metro.muze.nl/details/'\n\n/**\n * Symbols:\n * - isProxy: used to test if an object is a metro Proxy to another object\n * - source: used to return the actual source (target) of a metro Proxy\n */\nexport const symbols = {\n\tisProxy: Symbol('isProxy'),\n\tsource: Symbol('source')\n}\n\n/**\n * Metro HTTP Client with middleware support\n * @method get\n * @method post\n * @method put\n * @method delete\n * @method patch\n * @method head\n * @method options\n * @method query\n */\nclass Client\n{\n\t#options = {\n\t\turl: typeof window != 'undefined' ? window.location : 'https://localhost'\n\t}\n\t#verbs = ['get','post','put','delete','patch','head','options','query']\n\n\tstatic tracers = {}\n\n\t/**\n\t * @typedef {Object} ClientOptions\n\t * @property {Array} middlewares - list of middleware functions\n\t * @property {string|URL} url - default url of the client\n\t * @property {[string]} verbs - a list of verb methods to expose, e.g. ['get','post']\n\t * \n\t * Constructs a new metro client. Can have any number of params.\n\t * @params {ClientOptions|URL|Function|Client}\n\t * @returns {Client} - A metro client object with given or default verb methods\n\t */\n\tconstructor(...options)\n\t{\n\t\tfor (let option of options) {\n\t\t\tif (typeof option == 'string' || option instanceof String) {\n\t\t\t\tthis.#options.url = ''+option\n\t\t\t} else if (option instanceof Client) {\n\t\t\t\tObject.assign(this.#options, option.#options)\n\t\t\t} else if (option instanceof Function) {\n\t\t\t\tthis.#addMiddlewares([option])\n\t\t\t} else if (option && typeof option == 'object') {\n\t\t\t\tfor (let param in option) {\n\t\t\t\t\tif (param == 'middlewares') {\n\t\t\t\t\t\tthis.#addMiddlewares(option[param])\n\t\t\t\t\t} else if (typeof option[param] == 'function') {\n\t\t\t\t\t\tthis.#options[param] = option[param](this.#options[param], this.#options)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.#options[param] = option[param]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.#options.verbs) {\n\t\t\tthis.#verbs = this.#options.verbs\n\t\t\tdelete this.#options.verbs\n\t\t}\n\n\t\tfor (const verb of this.#verbs) {\n\t\t\tthis[verb] = async function(...options) {\n\t\t\t\treturn this.fetch(request(\n\t\t\t\t\tthis.#options,\n\t\t\t\t\t...options,\n\t\t\t\t\t{method: verb.toUpperCase()}\n\t\t\t\t))\n\t\t\t}\n\t\t}\n\t\tObject.freeze(this)\n\t}\n\n\t#addMiddlewares(middlewares)\n\t{\n\t\tif (typeof middlewares == 'function') {\n\t\t\tmiddlewares = [ middlewares ]\n\t\t}\n\t\tlet index = middlewares.findIndex(m => typeof m != 'function')\n\t\tif (index>=0) {\n\t\t\tthrow metroError('metro.client: middlewares must be a function or an array of functions '\n\t\t\t\t+metroURL+'client/invalid-middlewares-value/', middlewares[index])\n\t\t}\n\t\tif (!Array.isArray(this.#options.middlewares)) {\n\t\t\tthis.#options.middlewares = []\n\t\t}\n\t\tthis.#options.middlewares = this.#options.middlewares.concat(middlewares)\n\t}\n\n\t/**\n\t * Mimics the standard browser fetch method, but uses any middleware installed through\n\t * the constructor.\n\t * @param {Request|string|Object} - Required. The URL or Request object, accepts all types that are accepted by metro.request\n\t * @param {Object} - Optional. Any object that is accepted by metro.request\n\t * @return {Promise} - The metro.response to this request, or any other result as changed by any included middleware.\n\t */\n\tfetch(req, options)\n\t{\n\t\treq = request(req, options)\n\t\tif (!req.url) {\n\t\t\tthrow metroError('metro.client.'+req.method.toLowerCase()+': Missing url parameter '+metroURL+'client/missing-url-param/', req)\n\t\t}\n\t\tif (!options) {\n\t\t\toptions = {}\n\t\t}\n\t\tif (!(typeof options === 'object') \n\t\t\t|| Array.isArray(options)\n\t\t\t|| options instanceof String) \n\t\t{\n\t\t\tthrow metroError('metro.client.fetch: Options is not an object')\n\t\t}\n\n\t\tconst metrofetch = async function browserFetch(req)\n\t\t{\n\t\t\tif (req[symbols.isProxy]) {\n\t\t\t\t// even though a Proxy is supposed to be 'invisible'\n\t\t\t\t// fetch() doesn't work with the proxy (in Firefox), \n\t\t\t\t// you need the actual Request object here\n\t\t\t\treq = req[symbols.source]\n\t\t\t}\n\t\t\tconst res = await fetch(req)\n\t\t\treturn response(res)\n\t\t}\n\t\t\n\t\tlet middlewares = [metrofetch].concat(this.#options?.middlewares?.slice() || [])\n\t\toptions = Object.assign({}, this.#options, options)\n\t\t//@TODO: do this once in constructor?\n\t\tlet next\n\t\tfor (let middleware of middlewares) {\n\t\t\tnext = (function(next, middleware) {\n\t\t\t\treturn async function(req) {\n\t\t\t\t\tlet res\n\t\t\t\t\tlet tracers = Object.values(Client.tracers)\n\t\t\t\t\tfor(let tracer of tracers) {\n\t\t\t\t\t\tif (tracer.request) {\n\t\t\t\t\t\t\ttracer.request.call(tracer, req, middleware)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tres = await middleware(req, next)\n\t\t\t\t\tfor(let tracer of tracers) {\n\t\t\t\t\t\tif (tracer.response) {\n\t\t\t\t\t\t\ttracer.response.call(tracer, res, middleware)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn res\n\t\t\t\t}\t\t\t\t\t\t\t\t\n\t\t\t})(next, middleware)\n\t\t}\n\t\treturn next(req)\n\t}\n\n\twith(...options) {\n\t\treturn new Client(this, ...options)\n\t}\n}\n\n/**\n * Returns a new metro Client object.\n * @param {...ClientOptions|string|URL}\n * @return Client\n */\nexport function client(...options)\n{\n\treturn new Client(...options)\n}\n\nfunction appendHeaders(r, headers)\n{\n\tif (!Array.isArray(headers)) {\n\t\theaders = [headers]\n\t}\n\theaders.forEach((header) => {\n\t\tif (typeof header == 'function') {\n\t\t\tlet result = header(r.headers, r)\n\t\t\tif (result) {\n\t\t\t\tif (!Array.isArray(result)) {\n\t\t\t\t\tresult = [result]\n\t\t\t\t}\n\t\t\t\theaders = headers.concat(result)\n\t\t\t}\n\t\t}\n\t})\n\theaders.forEach((header) => {\n\t\tObject.entries(header).forEach(([name,value]) => {\t\t\t\n\t\t\tr.headers.append(name, value)\n\t\t})\n\t})\n}\n\nfunction bodyProxy(body, r)\n{\n\tlet source = r.body\n\tif (!source) {\n\t\t//Firefox does not allow access to Request.body (undefined)\n\t\t//Chrome and Nodejs do, so mimic the correct (documented)\n\t\t//result here\n\t\tif (body === null) {\n\t\t\tsource = new ReadableStream()\n\t\t} else if (body instanceof ReadableStream) {\n\t\t\tsource = body\n\t\t} else if (body instanceof Blob) {\n\t\t\tsource = body.stream()\n\t\t} else {\n\t\t\tsource = new ReadableStream({\n\t\t\t\tstart(controller) {\n\t\t\t\t\tlet chunk\n\t\t\t\t\tswitch(typeof body) {\n\t\t\t\t\t\tcase 'object':\n\t\t\t\t\t\t\tif (typeof body.toString == 'function') {\n\t\t\t\t\t\t\t\t// also catches URLSearchParams\n\t\t\t\t\t\t\t\tchunk = body.toString()\n\t\t\t\t\t\t\t} else if (body instanceof FormData) {\n\t\t\t\t\t\t\t\tchunk = new URLSearchParams(body).toString()\n\t\t\t\t\t\t\t} else if (body instanceof ArrayBuffer\n\t\t\t\t\t\t\t\t|| ArrayBuffer.isView(body)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t// catchs TypedArrays - e.g. Uint16Array\n\t\t\t\t\t\t\t\tchunk = body\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthrow metroError('Cannot convert body to ReadableStream', body)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'string':\n\t\t\t\t\t\tcase 'number':\n\t\t\t\t\t\tcase 'boolean':\n\t\t\t\t\t\t\tchunk = body\n\t\t\t\t\t\tbreak\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow metroError('Cannot convert body to ReadableStream', body)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcontroller.enqueue(chunk)\n\t\t\t\t\tcontroller.close()\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\treturn new Proxy(source, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch (prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn body\n\t\t\t\tbreak\n\t\t\t\tcase 'toString':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn ''+body\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (typeof body == 'object') {\n\t\t\t\tif (prop in body) {\n\t\t\t\t\tif (typeof body[prop] == 'function') {\n\t\t\t\t\t\treturn function(...args) {\n\t\t\t\t\t\t\treturn body[prop].apply(body, args)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn body[prop]\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (prop in target && prop != 'toString') {\n\t\t\t\t// skipped toString, since it has no usable output\n\t\t\t\t// and body may have its own toString\n\t\t\t\tif (typeof target[prop] == 'function') {\n\t\t\t\t\treturn function(...args) {\n\t\t\t\t\t\treturn target[prop].apply(target, args)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn target[prop]\n\t\t\t}\n\t\t},\n\t\thas(target, prop) {\n\t\t\treturn prop in body\n\t\t},\n\t\townKeys(target) {\n\t\t\treturn Reflect.ownKeys(body)\n\t\t},\n\t\tgetOwnPropertyDescriptor(target, prop) {\n\t\t\treturn Object.getOwnPropertyDescriptor(body,prop)\n\t\t}\n\t})\n}\n\nfunction getRequestParams(req, current)\n{\n\tlet params = current || {}\n\tif (!params.url && current.url) {\n\t\tparams.url = current.url\n\t}\n\t// function to fetch all relevant properties of a Request\n\tfor(let prop of ['method','headers','body','mode','credentials','cache','redirect',\n\t\t'referrer','referrerPolicy','integrity','keepalive','signal',\n\t\t'priority','url']) {\n\t\tif (typeof req[prop] == 'function') {\n\t\t\treq[prop](params[prop], params)\n\t\t} else if (typeof req[prop] != 'undefined') {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = url(params.url, req.url)\n\t\t\t} else if (prop == 'headers') {\n\t\t\t\tparams.headers = new Headers(current.headers)\n\t\t\t\tif (!(req.headers instanceof Headers)) {\n\t\t\t\t\treq.headers = new Headers(req.headers)\n\t\t\t\t}\n\t\t\t\tfor (let [key, value] of req.headers.entries()) {\n\t\t\t\t\tparams.headers.set(key, value)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparams[prop] = req[prop]\n\t\t\t}\n\t\t}\n\t}\n\treturn params\n}\n\n/**\n * @typedef {Request} MetroRequest\n * @property {Symbol(source)} - returns the target Request of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroRequest, with the given options added\n * @param {} ...options - request options, handled in order\n * \n * Returns a new metro Request object\n * @param {} ...options - request options, handled in order\n * @return {MetroRequest} - a new metro Request object\n */\nexport function request(...options)\n{\n\t// the standard Request constructor is a minefield\n\t// so first gather all the options together into a single\n\t// javascript object, then set it in one go\n\tlet requestParams = {\n\t\turl: typeof window != 'undefined' ? window.location : 'https://localhost/',\n\t\tduplex: 'half' // required when setting body to ReadableStream, just set it here by default already\n\t}\n\tfor (let option of options) {\n\t\tif (typeof option == 'string'\n\t\t\t|| option instanceof URL\n\t\t\t|| option instanceof URLSearchParams\n\t\t) {\n\t\t\trequestParams.url = url(requestParams.url, option)\n\t\t} else if (option && (\n\t\t\toption instanceof FormData\n\t\t\t|| option instanceof ReadableStream\n\t\t\t|| option instanceof Blob\n\t\t\t|| option instanceof ArrayBuffer\n\t\t\t|| option instanceof DataView\n\t\t)) {\n\t\t\trequestParams.body = option\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tObject.assign(requestParams, getRequestParams(option, requestParams))\n\t\t}\n\t}\n\tlet body = requestParams.body\n\tif (body) {\n\t\tif (typeof body == 'object'\n\t\t\t&& !(body instanceof String)\n\t\t\t&& !(body instanceof ReadableStream)\n\t\t\t&& !(body instanceof Blob)\n\t\t\t&& !(body instanceof ArrayBuffer)\n\t\t\t&& !(body instanceof DataView)\n\t\t\t&& !(body instanceof FormData)\n\t\t\t&& !(body instanceof URLSearchParams)\n\t\t\t&& (typeof TypedArray=='undefined' || !(body instanceof TypedArray))\n\t\t) {\n\t\t\trequestParams.body = JSON.stringify(body)\n\t\t}\n\t}\n\tlet r = new Request(requestParams.url, requestParams)\n\tObject.freeze(r)\n\treturn new Proxy(r, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\tif (body) { // body is kept in a seperate value, if it set earlier\n\t\t\t\t\t\t\toptions.unshift({ body }) // unshifted so it can be overridden by options\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn request(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'toString':\n\t\t\t\tcase 'toJSON':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn target[prop].apply(target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'blob':\n\t\t\t\tcase 'text':\n\t\t\t\tcase 'json':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn target[prop].apply(target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'body':\n\t\t\t\t\t// Request.body is always a ReadableStream\n\t\t\t\t\t// which is a horrible API, if you want to\n\t\t\t\t\t// allow middleware to alter the body\n\t\t\t\t\t// so we keep the original body, wrap a Proxy\n\t\t\t\t\t// around it to keep the ReadableStream api\n\t\t\t\t\t// accessible, but allow access to the original\n\t\t\t\t\t// body value as well\n\t\t\t\t\tif (!body) {\n\t\t\t\t\t\tbody = target.body\n\t\t\t\t\t}\n\t\t\t\t\tif (body) {\n\t\t\t\t\t\tif (body[symbols.isProxy]) {\n\t\t\t\t\t\t\treturn body\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn bodyProxy(body, target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn target[prop]\n\t\t}\n\t})\n}\n\nfunction getResponseParams(res, current)\n{\n\t// function to fetch all relevant properties of a Response\n\tlet params = current || {}\n\tif (!params.url && current.url) {\n\t\tparams.url = current.url\n\t}\n\tfor(let prop of ['status','statusText','headers','body','url','type','redirected']) {\n\t\tif (typeof res[prop] == 'function') {\n\t\t\tres[prop](params[prop], params)\n\t\t} else if (typeof res[prop] != 'undefined') {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = new URL(res.url, params.url || 'https://localhost/')\n\t\t\t} else {\n\t\t\t\tparams[prop] = res[prop]\n\t\t\t}\n\t\t}\n\t}\n\treturn params\n}\n\n/**\n * @typedef {Response} MetroResponse\n * @property {Symbol(source)} - returns the target Response of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroResponse, with the given options added\n * @param {} ...options - respomse options, handled in order\n * \n * Returns a new metro Response object\n * @param {} ...options - request options, handled in order\n * @return {MetroResponse} - a new metro Response object\n */\nexport function response(...options)\n{\n\tlet responseParams = {}\n\tfor (let option of options) {\n\t\tif (typeof option == 'string') {\n\t\t\tresponseParams.body = option\n\t\t} else if (option instanceof Response) {\n\t\t\tObject.assign(responseParams, getResponseParams(option, responseParams))\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tif (option instanceof FormData\n\t\t\t\t|| option instanceof Blob\n\t\t\t\t|| option instanceof ArrayBuffer\n\t\t\t\t|| option instanceof DataView\n\t\t\t\t|| option instanceof ReadableStream\n\t\t\t\t|| option instanceof URLSearchParams\n\t\t\t\t|| option instanceof String\n\t\t\t\t|| (typeof TypedArray != 'undefined' && option instanceof TypedArray)\n\t\t\t) {\n\t\t\t\tresponseParams.body = option\n\t\t\t} else {\n\t\t\t\tObject.assign(responseParams, getResponseParams(option, responseParams))\n\t\t\t}\n\t\t}\n\t}\n\tlet r = new Response(responseParams.body, responseParams)\t\n\tObject.freeze(r)\n\treturn new Proxy(r, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\treturn response(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'body':\n\t\t\t\t\tif (responseParams.body) {\n\t\t\t\t\t\tif (responseParams.body[symbols.isProxy]) {\n\t\t\t\t\t\t\treturn responseParams.body\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn bodyProxy(responseParams.body, target)\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn bodyProxy('',target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'ok':\n\t\t\t\t\treturn (target.status>=200) && (target.status<400)\n\t\t\t\tbreak\n\t\t\t\tcase 'headers':\n\t\t\t\t\treturn target.headers\n\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\tif (prop in responseParams && prop != 'toString') {\n\t\t\t\t\t\treturn responseParams[prop]\n\t\t\t\t\t}\n\t\t\t\t\tif (prop in target && prop != 'toString') {\n\t\t\t\t\t\t// skipped toString, since it has no usable output\n\t\t\t\t\t\t// and body may have its own toString\n\t\t\t\t\t\tif (typeof target[prop] == 'function') {\n\t\t\t\t\t\t\treturn function(...args) {\n\t\t\t\t\t\t\t\treturn target[prop].apply(target, args)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn target[prop]\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn undefined\n\t\t}\n\t})\n}\n\nfunction appendSearchParams(url, params) {\n\tif (typeof params == 'function') {\n\t\t params(url.searchParams, url)\n\t} else {\n\t\tparams = new URLSearchParams(params)\n\t\tparams.forEach((value,key) => {\n\t\t\turl.searchParams.append(key, value)\n\t\t})\n\t}\n}\n\n/**\n * @typedef {URL} MetroURL\n * @property {Symbol(source)} - returns the target Request of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroRequest, with the given options added\n * @param {} ...options - url options, handled in order\n * \n * Returns a new metro URL object\n * @param {} ...options - url options, handled in order\n * @return {MetroURL} - a new metro URL object\n */\nexport function url(...options)\n{\n\tlet validParams = ['hash','host','hostname','href',\n\t\t\t'password','pathname','port','protocol','username','search','searchParams']\n\tlet u = new URL('https://localhost/')\n\tfor (let option of options) {\n\t\tif (typeof option == 'string' || option instanceof String) {\n\t\t\t// option is a relative or absolute url\n\t\t\tu = new URL(option, u)\n\t\t} else if (option instanceof URL \n\t\t\t|| (typeof Location != 'undefined' \n\t\t\t\t&& option instanceof Location)\n\t\t) {\n\t\t\tu = new URL(option)\n\t\t} else if (option instanceof URLSearchParams) {\n\t\t\tappendSearchParams(u, option)\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tfor (let param in option) {\n\t\t\t\tif (param=='search') {\n\t\t\t\t\tif (typeof option.search == 'function') {\n\t\t\t\t\t\toption.search(u.search, u)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tu.search = new URLSearchParams(option.search)\n\t\t\t\t\t}\n\t\t\t\t} else if (param=='searchParams') {\n\t\t\t\t\tappendSearchParams(u, option.searchParams)\n\t\t\t\t} else {\n\t\t\t\t\tif (!validParams.includes(param)) {\n\t\t\t\t\t\tthrow metroError('metro.url: unknown url parameter '+metroURL+'url/unknown-param-name/', param)\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof option[param] == 'function') {\n\t\t\t\t\t\toption[param](u[param], u)\n\t\t\t\t\t} else if (\n\t\t\t\t\t\ttypeof option[param] == 'string' || option[param] instanceof String \n\t\t\t\t\t\t|| typeof option[param] == 'number' || option[param] instanceof Number\n\t\t\t\t\t\t|| typeof option[param] == 'boolean' || option[param] instanceof Boolean\n\t\t\t\t\t) {\n\t\t\t\t\t\tu[param] = ''+option[param]\n\t\t\t\t\t} else if (typeof option[param] == 'object' && option[param].toString) {\n\t\t\t\t\t\tu[param] = option[param].toString()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow metroError('metro.url: unsupported value for '+param+' '+metroURL+'url/unsupported-param-value/', options[param])\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow metroError('metro.url: unsupported option value '+metroURL+'url/unsupported-option-value/', option)\n\t\t}\n\t}\n\tObject.freeze(u)\n\treturn new Proxy(u, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\treturn url(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'toString':\n\t\t\t\tcase 'toJSON':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn target[prop]()\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn target[prop]\n\t\t}\n\t})\n}\n\n/**\n * @typedef {FormData} MetroFormData\n * @property {Symbol(source)} - returns the target Request of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroRequest, with the given options added\n * @param {} ...options - url options, handled in order\n * \n * Returns a new metro FormData object\n * @param {} ...options - formdata options, handled in order\n * @return {MetroURL} - a new metro FormData object\n */\nexport function formdata(...options)\n{\n\tvar params = new FormData()\n\tfor (let option of options) {\n\t\tif (option instanceof FormData) {\n\t\t\tfor (let entry of option.entries()) {\n\t\t\t\tparams.append(entry[0],entry[1])\n\t\t\t}\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tfor (let entry of Object.entries(option)) {\n\t\t\t\tif (Array.isArray(entry[1])) {\n\t\t\t\t\tfor (let value of entry[1]) {\n\t\t\t\t\t\tparams.append(entry[0], value)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tparams.append(entry[0],entry[1])\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new metroError('metro.formdata: unknown option type, only FormData or Object supported',option)\n\t\t}\n\t}\n\tObject.freeze(params)\n\treturn new Proxy(params, {\n\t\tget: (target,prop,receiver) => {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\treturn formdata(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'toString':\n\t\t\t\tcase 'toJSON':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn target[prop]()\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn target[prop]\n\t\t}\n\t})\n}\n\nconst metroConsole = {\n\terror: (message, ...details) => {\n\t\tconsole.error('Ⓜ️ ',message, ...details)\n\t},\n\tinfo: (message, ...details) => {\n\t\tconsole.info('Ⓜ️ ',message, ...details)\n\t},\n\tgroup: (name) => {\n\t\tconsole.group('Ⓜ️ '+name)\n\t},\n\tgroupEnd: (name) => {\n\t\tconsole.groupEnd('Ⓜ️ '+name)\n\t}\n}\n\n\n/**\n * Custom Metro Error function that outputs to the console then throws an error\n */\nexport function metroError(message, ...details) {\n\tmetroConsole.error(message, ...details)\n\treturn new Error(message, ...details)\n}\n\n/**\n * Set of debugging tools to trace the request - response flow\n * Tracer are run on all metro fetch calls\n */\nexport const trace = {\n\t/**\n\t * Adds a named tracer function\n\t * @param {string} name - the name of the tracer\n\t * @param {Function} tracer - the tracer function to call\n\t */\n\tadd(name, tracer) {\n\t\tClient.tracers[name] = tracer\n\t},\n\t/**\n\t * Removes a named tracer function\n\t * @param {string} name\n\t */\n\tdelete(name) {\n\t\tdelete Client.tracers[name]\n\t},\n\t/**\n\t * Removes all tracer functions\n\t */\n\tclear() {\n\t\tClient.tracers = {}\n\t},\n\t/**\n\t * Returns a set of request and response tracer functions that use the\n\t * console.group feature to shows nested request/response pairs, with\n\t * most commonly needed information for debugging\n\t */\n\tgroup() {\n\t\tlet group = 0;\n\t\treturn {\n\t\t\trequest: (req, middleware) => {\n\t\t\t\tgroup++\n\t\t\t\tmetroConsole.group(group)\n\t\t\t\tmetroConsole.info(req?.url, req, middleware)\n\t\t\t},\n\t\t\tresponse: (res, middleware) => {\n\t\t\t\tmetroConsole.info(res?.body ? res.body[symbols.source]: null, res, middleware)\n\t\t\t\tmetroConsole.groupEnd(group)\n\t\t\t\tgroup--\n\t\t\t}\n\t\t}\n\t}\n}\n","import * as metro from './metro.mjs'\n\nwindow.metro = metro\n"],"names":["$parcel$export","e","n","v","s","Object","defineProperty","get","set","enumerable","configurable","$parcel$global","globalThis","$parcel$modules","$parcel$inits","parcelRequire","id","exports","init","module","call","err","Error","code","register","parcelRegister","$86c8ab3a59b0bae1$export$47616e9f7f5fe113","$86c8ab3a59b0bae1$export$b5fe3f66a567bec0","$86c8ab3a59b0bae1$export$7079e2c78c274c66","$86c8ab3a59b0bae1$export$785bb8ef7fad1f74","$86c8ab3a59b0bae1$export$388e0302ca0d9a41","$86c8ab3a59b0bae1$export$128fa18b7194ef","$86c8ab3a59b0bae1$export$5de500aade6bf050","options","params","FormData","option","entry","entries","append","Array","isArray","value","freeze","Proxy","target","prop","receiver","isProxy","source","$86c8ab3a59b0bae1$export$357889f174732d38","$86c8ab3a59b0bae1$var$metroURL","Symbol","$86c8ab3a59b0bae1$var$Client","url","window","location","verbs","tracers","constructor","String","assign","Function","addMiddlewares","param","verb","fetch","method","toUpperCase","middlewares","index","findIndex","m","concat","req","next","toLowerCase","slice","middleware","res","values","tracer","request","response","with","$86c8ab3a59b0bae1$var$bodyProxy","body","r","ReadableStream","Blob","stream","start","controller","chunk","toString","URLSearchParams","ArrayBuffer","isView","enqueue","close","args","apply","has","ownKeys","Reflect","getOwnPropertyDescriptor","requestParams","duplex","URL","DataView","$86c8ab3a59b0bae1$var$getRequestParams","current","key","headers","Headers","TypedArray","JSON","stringify","Request","unshift","$86c8ab3a59b0bae1$var$getResponseParams","responseParams","Response","status","$86c8ab3a59b0bae1$var$appendSearchParams","searchParams","forEach","validParams","u","Location","search","includes","Number","Boolean","message","details","console","error","info","name","group","groupEnd","$86c8ab3a59b0bae1$var$metroConsole","add","delete","clear","$hkeot","metro"],"version":3,"file":"browser.js.map","sourceRoot":"../"} \ No newline at end of file +{"mappings":"A,S,E,C,C,C,C,C,C,C,E,O,c,C,E,E,C,I,E,I,E,W,C,E,a,C,C,E,C,I,E,W,E,C,E,E,C,E,E,E,iB,A,O,I,A,C,E,S,C,E,G,K,E,O,C,C,E,C,O,C,G,K,E,C,I,E,C,C,E,A,Q,C,C,E,C,I,E,C,G,E,Q,C,C,E,O,C,C,E,C,E,E,I,C,E,O,C,E,E,O,E,E,O,A,C,I,E,A,M,uB,E,I,O,E,I,C,mB,C,C,E,Q,C,S,C,C,C,E,C,C,E,C,C,E,E,iB,C,G,A,C,E,E,Q,A,E,Q,S,C,C,C,E,E,E,O,C,U,I,G,E,E,O,C,U,I,G,E,E,O,C,a,I,G,E,E,O,C,W,I,G,E,E,O,C,S,I,G,E,E,O,C,M,I,G,E,E,O,C,W,ICipBO,SAAS,EAAS,GAAG,CAAO,EAElC,IAAI,EAAS,IAAI,SACjB,IAAK,IAAI,KAAU,EAClB,GAAI,aAAkB,SACrB,IAAK,IAAI,KAAS,EAAO,OAAO,GAC/B,EAAO,MAAM,CAAC,CAAK,CAAC,EAAE,CAAC,CAAK,CAAC,EAAE,OAE1B,GAAI,GAAU,AAAiB,UAAjB,OAAO,EAC3B,IAAK,IAAI,KAAS,OAAO,OAAO,CAAC,GAChC,GAAI,MAAM,OAAO,CAAC,CAAK,CAAC,EAAE,EACzB,IAAK,IAAI,KAAS,CAAK,CAAC,EAAE,CACzB,EAAO,MAAM,CAAC,CAAK,CAAC,EAAE,CAAE,QAGzB,EAAO,MAAM,CAAC,CAAK,CAAC,EAAE,CAAC,CAAK,CAAC,EAAE,OAIjC,MAAM,IAAI,EAAW,yEAAyE,GAIhG,OADA,OAAO,MAAM,CAAC,GACP,IAAI,MAAM,EAAQ,CACxB,IAAK,CAAC,EAAO,EAAK,KACjB,OAAO,GACN,KAAK,EAAQ,OAAO,CACnB,MAAO,CAAA,CAER,MAAK,EAAQ,MAAM,CAClB,OAAO,CAER,KAAK,OACJ,OAAO,SAAS,GAAG,CAAO,EACzB,OAAO,EAAS,KAAW,EAC5B,CAQF,CACA,OAAO,CAAM,CAAC,EAAK,AACpB,CACD,EACD,G,E,E,O,C,Q,I,GA7rBA,IAAM,EAAW,iCAOJ,EAAU,CACtB,QAAS,OAAO,WAChB,OAAQ,OAAO,SAChB,CAaA,OAAM,EAEL,CAAA,CA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","sources":["","src/metro.mjs","src/browser.mjs"],"sourcesContent":["\nfunction $parcel$export(e, n, v, s) {\n Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});\n}\n\n var $parcel$global = globalThis;\n \nvar $parcel$modules = {};\nvar $parcel$inits = {};\n\nvar parcelRequire = $parcel$global[\"parcelRequire94c2\"];\n\nif (parcelRequire == null) {\n parcelRequire = function(id) {\n if (id in $parcel$modules) {\n return $parcel$modules[id].exports;\n }\n if (id in $parcel$inits) {\n var init = $parcel$inits[id];\n delete $parcel$inits[id];\n var module = {id: id, exports: {}};\n $parcel$modules[id] = module;\n init.call(module.exports, module, module.exports);\n return module.exports;\n }\n var err = new Error(\"Cannot find module '\" + id + \"'\");\n err.code = 'MODULE_NOT_FOUND';\n throw err;\n };\n\n parcelRequire.register = function register(id, init) {\n $parcel$inits[id] = init;\n };\n\n $parcel$global[\"parcelRequire94c2\"] = parcelRequire;\n}\n\nvar parcelRegister = parcelRequire.register;\nparcelRegister(\"hkeot\", function(module, exports) {\n\n$parcel$export(module.exports, \"symbols\", () => $86c8ab3a59b0bae1$export$47616e9f7f5fe113);\n$parcel$export(module.exports, \"request\", () => $86c8ab3a59b0bae1$export$b5fe3f66a567bec0);\n$parcel$export(module.exports, \"metroError\", () => $86c8ab3a59b0bae1$export$7079e2c78c274c66);\n$parcel$export(module.exports, \"response\", () => $86c8ab3a59b0bae1$export$785bb8ef7fad1f74);\n$parcel$export(module.exports, \"client\", () => $86c8ab3a59b0bae1$export$388e0302ca0d9a41);\n$parcel$export(module.exports, \"url\", () => $86c8ab3a59b0bae1$export$128fa18b7194ef);\n$parcel$export(module.exports, \"formdata\", () => $86c8ab3a59b0bae1$export$5de500aade6bf050);\n$parcel$export(module.exports, \"trace\", () => $86c8ab3a59b0bae1$export$357889f174732d38);\n/**\n * base URL used to link to more information about an error message\n */ const $86c8ab3a59b0bae1$var$metroURL = 'https://metro.muze.nl/details/';\nconst $86c8ab3a59b0bae1$export$47616e9f7f5fe113 = {\n isProxy: Symbol('isProxy'),\n source: Symbol('source')\n};\n/**\n * Metro HTTP Client with middleware support\n * @method get\n * @method post\n * @method put\n * @method delete\n * @method patch\n * @method head\n * @method options\n * @method query\n */ class $86c8ab3a59b0bae1$var$Client {\n #options = {\n url: typeof window != 'undefined' ? window.location : 'https://localhost'\n };\n #verbs = [\n 'get',\n 'post',\n 'put',\n 'delete',\n 'patch',\n 'head',\n 'options',\n 'query'\n ];\n static tracers = {};\n /**\n\t * @typedef {Object} ClientOptions\n\t * @property {Array} middlewares - list of middleware functions\n\t * @property {string|URL} url - default url of the client\n\t * @property {[string]} verbs - a list of verb methods to expose, e.g. ['get','post']\n\t * \n\t * Constructs a new metro client. Can have any number of params.\n\t * @params {ClientOptions|URL|Function|Client}\n\t * @returns {Client} - A metro client object with given or default verb methods\n\t */ constructor(...options){\n for (let option of options){\n if (typeof option == 'string' || option instanceof String) this.#options.url = '' + option;\n else if (option instanceof $86c8ab3a59b0bae1$var$Client) Object.assign(this.#options, option.#options);\n else if (option instanceof Function) this.#addMiddlewares([\n option\n ]);\n else if (option && typeof option == 'object') for(let param in option){\n if (param == 'middlewares') this.#addMiddlewares(option[param]);\n else if (typeof option[param] == 'function') this.#options[param] = option[param](this.#options[param], this.#options);\n else this.#options[param] = option[param];\n }\n }\n if (this.#options.verbs) {\n this.#verbs = this.#options.verbs;\n delete this.#options.verbs;\n }\n for (const verb of this.#verbs)this[verb] = async function(...options) {\n return this.fetch($86c8ab3a59b0bae1$export$b5fe3f66a567bec0(this.#options, ...options, {\n method: verb.toUpperCase()\n }));\n };\n Object.freeze(this);\n }\n #addMiddlewares(middlewares) {\n if (typeof middlewares == 'function') middlewares = [\n middlewares\n ];\n let index = middlewares.findIndex((m)=>typeof m != 'function');\n if (index >= 0) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('metro.client: middlewares must be a function or an array of functions ' + $86c8ab3a59b0bae1$var$metroURL + 'client/invalid-middlewares-value/', middlewares[index]);\n if (!Array.isArray(this.#options.middlewares)) this.#options.middlewares = [];\n this.#options.middlewares = this.#options.middlewares.concat(middlewares);\n }\n /**\n\t * Mimics the standard browser fetch method, but uses any middleware installed through\n\t * the constructor.\n\t * @param {Request|string|Object} - Required. The URL or Request object, accepts all types that are accepted by metro.request\n\t * @param {Object} - Optional. Any object that is accepted by metro.request\n\t * @return {Promise} - The metro.response to this request, or any other result as changed by any included middleware.\n\t */ fetch(req, options) {\n req = $86c8ab3a59b0bae1$export$b5fe3f66a567bec0(req, options);\n if (!req.url) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('metro.client.' + req.method.toLowerCase() + ': Missing url parameter ' + $86c8ab3a59b0bae1$var$metroURL + 'client/missing-url-param/', req);\n if (!options) options = {};\n if (!(typeof options === 'object') || Array.isArray(options) || options instanceof String) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('metro.client.fetch: Options is not an object');\n const metrofetch = async function browserFetch(req) {\n if (req[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy]) // even though a Proxy is supposed to be 'invisible'\n // fetch() doesn't work with the proxy (in Firefox), \n // you need the actual Request object here\n req = req[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.source];\n const res = await fetch(req);\n return $86c8ab3a59b0bae1$export$785bb8ef7fad1f74(res);\n };\n let middlewares = [\n metrofetch\n ].concat(this.#options?.middlewares?.slice() || []);\n options = Object.assign({}, this.#options, options);\n //@TODO: do this once in constructor?\n let next;\n for (let middleware of middlewares)next = function(next, middleware) {\n return async function(req) {\n let res;\n let tracers = Object.values($86c8ab3a59b0bae1$var$Client.tracers);\n for (let tracer of tracers)if (tracer.request) tracer.request.call(tracer, req, middleware);\n res = await middleware(req, next);\n for (let tracer of tracers)if (tracer.response) tracer.response.call(tracer, res, middleware);\n return res;\n };\n }(next, middleware);\n return next(req);\n }\n with(...options) {\n return new $86c8ab3a59b0bae1$var$Client(this, ...options);\n }\n}\nfunction $86c8ab3a59b0bae1$export$388e0302ca0d9a41(...options) {\n return new $86c8ab3a59b0bae1$var$Client(...options);\n}\nfunction $86c8ab3a59b0bae1$var$appendHeaders(r, headers) {\n if (!Array.isArray(headers)) headers = [\n headers\n ];\n headers.forEach((header)=>{\n if (typeof header == 'function') {\n let result = header(r.headers, r);\n if (result) {\n if (!Array.isArray(result)) result = [\n result\n ];\n headers = headers.concat(result);\n }\n }\n });\n headers.forEach((header)=>{\n Object.entries(header).forEach(([name, value])=>{\n r.headers.append(name, value);\n });\n });\n}\nfunction $86c8ab3a59b0bae1$var$bodyProxy(body, r) {\n let source = r.body;\n if (!source) {\n //Firefox does not allow access to Request.body (undefined)\n //Chrome and Nodejs do, so mimic the correct (documented)\n //result here\n if (body === null) source = new ReadableStream();\n else if (body instanceof ReadableStream) source = body;\n else if (body instanceof Blob) source = body.stream();\n else source = new ReadableStream({\n start (controller) {\n let chunk;\n switch(typeof body){\n case 'object':\n if (typeof body.toString == 'function') // also catches URLSearchParams\n chunk = body.toString();\n else if (body instanceof FormData) chunk = new URLSearchParams(body).toString();\n else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) // catchs TypedArrays - e.g. Uint16Array\n chunk = body;\n else throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('Cannot convert body to ReadableStream', body);\n break;\n case 'string':\n case 'number':\n case 'boolean':\n chunk = body;\n break;\n default:\n throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('Cannot convert body to ReadableStream', body);\n }\n controller.enqueue(chunk);\n controller.close();\n }\n });\n }\n return new Proxy(source, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return body;\n case 'toString':\n return function() {\n return '' + body;\n };\n }\n if (typeof body == 'object') {\n if (prop in body) {\n if (typeof body[prop] == 'function') return function(...args) {\n return body[prop].apply(body, args);\n };\n return body[prop];\n }\n }\n if (prop in target && prop != 'toString') {\n // skipped toString, since it has no usable output\n // and body may have its own toString\n if (typeof target[prop] == 'function') return function(...args) {\n return target[prop].apply(target, args);\n };\n return target[prop];\n }\n },\n has (target, prop) {\n return prop in body;\n },\n ownKeys (target) {\n return Reflect.ownKeys(body);\n },\n getOwnPropertyDescriptor (target, prop) {\n return Object.getOwnPropertyDescriptor(body, prop);\n }\n });\n}\nfunction $86c8ab3a59b0bae1$var$getRequestParams(req, current) {\n let params = current || {};\n if (!params.url && current.url) params.url = current.url;\n // function to fetch all relevant properties of a Request\n for (let prop of [\n 'method',\n 'headers',\n 'body',\n 'mode',\n 'credentials',\n 'cache',\n 'redirect',\n 'referrer',\n 'referrerPolicy',\n 'integrity',\n 'keepalive',\n 'signal',\n 'priority',\n 'url'\n ]){\n if (typeof req[prop] == 'function') req[prop](params[prop], params);\n else if (typeof req[prop] != 'undefined') {\n if (prop == 'url') params.url = $86c8ab3a59b0bae1$export$128fa18b7194ef(params.url, req.url);\n else if (prop == 'headers') {\n params.headers = new Headers(current.headers);\n if (!(req.headers instanceof Headers)) req.headers = new Headers(req.headers);\n for (let [key, value] of req.headers.entries())params.headers.set(key, value);\n } else params[prop] = req[prop];\n }\n }\n return params;\n}\nfunction $86c8ab3a59b0bae1$export$b5fe3f66a567bec0(...options) {\n // the standard Request constructor is a minefield\n // so first gather all the options together into a single\n // javascript object, then set it in one go\n let requestParams = {\n url: typeof window != 'undefined' ? window.location : 'https://localhost/',\n duplex: 'half' // required when setting body to ReadableStream, just set it here by default already\n };\n for (let option of options){\n if (typeof option == 'string' || option instanceof URL || option instanceof URLSearchParams) requestParams.url = $86c8ab3a59b0bae1$export$128fa18b7194ef(requestParams.url, option);\n else if (option && (option instanceof FormData || option instanceof ReadableStream || option instanceof Blob || option instanceof ArrayBuffer || option instanceof DataView)) requestParams.body = option;\n else if (option && typeof option == 'object') Object.assign(requestParams, $86c8ab3a59b0bae1$var$getRequestParams(option, requestParams));\n }\n let body = requestParams.body;\n if (body) {\n if (typeof body == 'object' && !(body instanceof String) && !(body instanceof ReadableStream) && !(body instanceof Blob) && !(body instanceof ArrayBuffer) && !(body instanceof DataView) && !(body instanceof FormData) && !(body instanceof URLSearchParams) && (typeof TypedArray == 'undefined' || !(body instanceof TypedArray))) requestParams.body = JSON.stringify(body);\n }\n let r = new Request(requestParams.url, requestParams);\n Object.freeze(r);\n return new Proxy(r, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case 'with':\n return function(...options) {\n if (body) options.unshift({\n body: body\n }) // unshifted so it can be overridden by options\n ;\n return $86c8ab3a59b0bae1$export$b5fe3f66a567bec0(target, ...options);\n };\n case 'toString':\n case 'toJSON':\n return function() {\n return target[prop].apply(target);\n };\n case 'blob':\n case 'text':\n case 'json':\n return function() {\n return target[prop].apply(target);\n };\n case 'body':\n // Request.body is always a ReadableStream\n // which is a horrible API, if you want to\n // allow middleware to alter the body\n // so we keep the original body, wrap a Proxy\n // around it to keep the ReadableStream api\n // accessible, but allow access to the original\n // body value as well\n if (!body) body = target.body;\n if (body) {\n if (body[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy]) return body;\n return $86c8ab3a59b0bae1$var$bodyProxy(body, target);\n }\n break;\n }\n return target[prop];\n }\n });\n}\nfunction $86c8ab3a59b0bae1$var$getResponseParams(res, current) {\n // function to fetch all relevant properties of a Response\n let params = current || {};\n if (!params.url && current.url) params.url = current.url;\n for (let prop of [\n 'status',\n 'statusText',\n 'headers',\n 'body',\n 'url',\n 'type',\n 'redirected'\n ]){\n if (typeof res[prop] == 'function') res[prop](params[prop], params);\n else if (typeof res[prop] != 'undefined') {\n if (prop == 'url') params.url = new URL(res.url, params.url || 'https://localhost/');\n else params[prop] = res[prop];\n }\n }\n return params;\n}\nfunction $86c8ab3a59b0bae1$export$785bb8ef7fad1f74(...options) {\n let responseParams = {};\n for (let option of options){\n if (typeof option == 'string') responseParams.body = option;\n else if (option instanceof Response) Object.assign(responseParams, $86c8ab3a59b0bae1$var$getResponseParams(option, responseParams));\n else if (option && typeof option == 'object') {\n if (option instanceof FormData || option instanceof Blob || option instanceof ArrayBuffer || option instanceof DataView || option instanceof ReadableStream || option instanceof URLSearchParams || option instanceof String || typeof TypedArray != 'undefined' && option instanceof TypedArray) responseParams.body = option;\n else Object.assign(responseParams, $86c8ab3a59b0bae1$var$getResponseParams(option, responseParams));\n }\n }\n let r = new Response(responseParams.body, responseParams);\n Object.freeze(r);\n return new Proxy(r, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case 'with':\n return function(...options) {\n return $86c8ab3a59b0bae1$export$785bb8ef7fad1f74(target, ...options);\n };\n case 'body':\n if (responseParams.body) {\n if (responseParams.body[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy]) return responseParams.body;\n return $86c8ab3a59b0bae1$var$bodyProxy(responseParams.body, target);\n } else return $86c8ab3a59b0bae1$var$bodyProxy('', target);\n break;\n case 'ok':\n return target.status >= 200 && target.status < 400;\n case 'headers':\n return target.headers;\n default:\n if (prop in responseParams && prop != 'toString') return responseParams[prop];\n if (prop in target && prop != 'toString') {\n // skipped toString, since it has no usable output\n // and body may have its own toString\n if (typeof target[prop] == 'function') return function(...args) {\n return target[prop].apply(target, args);\n };\n return target[prop];\n }\n break;\n }\n return undefined;\n }\n });\n}\nfunction $86c8ab3a59b0bae1$var$appendSearchParams(url, params) {\n if (typeof params == 'function') params(url.searchParams, url);\n else {\n params = new URLSearchParams(params);\n params.forEach((value, key)=>{\n url.searchParams.append(key, value);\n });\n }\n}\nfunction $86c8ab3a59b0bae1$export$128fa18b7194ef(...options) {\n let validParams = [\n 'hash',\n 'host',\n 'hostname',\n 'href',\n 'password',\n 'pathname',\n 'port',\n 'protocol',\n 'username',\n 'search',\n 'searchParams'\n ];\n let u = new URL('https://localhost/');\n for (let option of options){\n if (typeof option == 'string' || option instanceof String) // option is a relative or absolute url\n u = new URL(option, u);\n else if (option instanceof URL || typeof Location != 'undefined' && option instanceof Location) u = new URL(option);\n else if (option instanceof URLSearchParams) $86c8ab3a59b0bae1$var$appendSearchParams(u, option);\n else if (option && typeof option == 'object') for(let param in option){\n if (param == 'search') {\n if (typeof option.search == 'function') option.search(u.search, u);\n else u.search = new URLSearchParams(option.search);\n } else if (param == 'searchParams') $86c8ab3a59b0bae1$var$appendSearchParams(u, option.searchParams);\n else {\n if (!validParams.includes(param)) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('metro.url: unknown url parameter ' + $86c8ab3a59b0bae1$var$metroURL + 'url/unknown-param-name/', param);\n if (typeof option[param] == 'function') option[param](u[param], u);\n else if (typeof option[param] == 'string' || option[param] instanceof String || typeof option[param] == 'number' || option[param] instanceof Number || typeof option[param] == 'boolean' || option[param] instanceof Boolean) u[param] = '' + option[param];\n else if (typeof option[param] == 'object' && option[param].toString) u[param] = option[param].toString();\n else throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('metro.url: unsupported value for ' + param + ' ' + $86c8ab3a59b0bae1$var$metroURL + 'url/unsupported-param-value/', options[param]);\n }\n }\n else throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('metro.url: unsupported option value ' + $86c8ab3a59b0bae1$var$metroURL + 'url/unsupported-option-value/', option);\n }\n Object.freeze(u);\n return new Proxy(u, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case 'with':\n return function(...options) {\n return $86c8ab3a59b0bae1$export$128fa18b7194ef(target, ...options);\n };\n case 'toString':\n case 'toJSON':\n return function() {\n return target[prop]();\n };\n }\n return target[prop];\n }\n });\n}\nfunction $86c8ab3a59b0bae1$export$5de500aade6bf050(...options) {\n var params = new FormData();\n for (let option of options){\n if (option instanceof FormData) for (let entry of option.entries())params.append(entry[0], entry[1]);\n else if (option && typeof option == 'object') for (let entry of Object.entries(option)){\n if (Array.isArray(entry[1])) for (let value of entry[1])params.append(entry[0], value);\n else params.append(entry[0], entry[1]);\n }\n else throw new $86c8ab3a59b0bae1$export$7079e2c78c274c66('metro.formdata: unknown option type, only FormData or Object supported', option);\n }\n Object.freeze(params);\n return new Proxy(params, {\n get: (target, prop, receiver)=>{\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case 'with':\n return function(...options) {\n return $86c8ab3a59b0bae1$export$5de500aade6bf050(target, ...options);\n };\n }\n return target[prop];\n }\n });\n}\nconst $86c8ab3a59b0bae1$var$metroConsole = {\n error: (message, ...details)=>{\n console.error(\"\\u24C2\\uFE0F \", message, ...details);\n },\n info: (message, ...details)=>{\n console.info(\"\\u24C2\\uFE0F \", message, ...details);\n },\n group: (name)=>{\n console.group(\"\\u24C2\\uFE0F \" + name);\n },\n groupEnd: (name)=>{\n console.groupEnd(\"\\u24C2\\uFE0F \" + name);\n }\n};\nfunction $86c8ab3a59b0bae1$export$7079e2c78c274c66(message, ...details) {\n $86c8ab3a59b0bae1$var$metroConsole.error(message, ...details);\n return new Error(message, ...details);\n}\nconst $86c8ab3a59b0bae1$export$357889f174732d38 = {\n /**\n\t * Adds a named tracer function\n\t * @param {string} name - the name of the tracer\n\t * @param {Function} tracer - the tracer function to call\n\t */ add (name, tracer) {\n $86c8ab3a59b0bae1$var$Client.tracers[name] = tracer;\n },\n /**\n\t * Removes a named tracer function\n\t * @param {string} name\n\t */ delete (name) {\n delete $86c8ab3a59b0bae1$var$Client.tracers[name];\n },\n /**\n\t * Removes all tracer functions\n\t */ clear () {\n $86c8ab3a59b0bae1$var$Client.tracers = {};\n },\n /**\n\t * Returns a set of request and response tracer functions that use the\n\t * console.group feature to shows nested request/response pairs, with\n\t * most commonly needed information for debugging\n\t */ group () {\n let group = 0;\n return {\n request: (req, middleware)=>{\n group++;\n $86c8ab3a59b0bae1$var$metroConsole.group(group);\n $86c8ab3a59b0bae1$var$metroConsole.info(req?.url, req, middleware);\n },\n response: (res, middleware)=>{\n $86c8ab3a59b0bae1$var$metroConsole.info(res?.body ? res.body[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.source] : null, res, middleware);\n $86c8ab3a59b0bae1$var$metroConsole.groupEnd(group);\n group--;\n }\n };\n }\n};\n\n});\n\n\nvar $hkeot = parcelRequire(\"hkeot\");\nwindow.metro = $hkeot;\n\n\n//# sourceMappingURL=browser.js.map\n","/**\n * base URL used to link to more information about an error message\n */\nconst metroURL = 'https://metro.muze.nl/details/'\n\n/**\n * Symbols:\n * - isProxy: used to test if an object is a metro Proxy to another object\n * - source: used to return the actual source (target) of a metro Proxy\n */\nexport const symbols = {\n\tisProxy: Symbol('isProxy'),\n\tsource: Symbol('source')\n}\n\n/**\n * Metro HTTP Client with middleware support\n * @method get\n * @method post\n * @method put\n * @method delete\n * @method patch\n * @method head\n * @method options\n * @method query\n */\nclass Client\n{\n\t#options = {\n\t\turl: typeof window != 'undefined' ? window.location : 'https://localhost'\n\t}\n\t#verbs = ['get','post','put','delete','patch','head','options','query']\n\n\tstatic tracers = {}\n\n\t/**\n\t * @typedef {Object} ClientOptions\n\t * @property {Array} middlewares - list of middleware functions\n\t * @property {string|URL} url - default url of the client\n\t * @property {[string]} verbs - a list of verb methods to expose, e.g. ['get','post']\n\t * \n\t * Constructs a new metro client. Can have any number of params.\n\t * @params {ClientOptions|URL|Function|Client}\n\t * @returns {Client} - A metro client object with given or default verb methods\n\t */\n\tconstructor(...options)\n\t{\n\t\tfor (let option of options) {\n\t\t\tif (typeof option == 'string' || option instanceof String) {\n\t\t\t\tthis.#options.url = ''+option\n\t\t\t} else if (option instanceof Client) {\n\t\t\t\tObject.assign(this.#options, option.#options)\n\t\t\t} else if (option instanceof Function) {\n\t\t\t\tthis.#addMiddlewares([option])\n\t\t\t} else if (option && typeof option == 'object') {\n\t\t\t\tfor (let param in option) {\n\t\t\t\t\tif (param == 'middlewares') {\n\t\t\t\t\t\tthis.#addMiddlewares(option[param])\n\t\t\t\t\t} else if (typeof option[param] == 'function') {\n\t\t\t\t\t\tthis.#options[param] = option[param](this.#options[param], this.#options)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.#options[param] = option[param]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.#options.verbs) {\n\t\t\tthis.#verbs = this.#options.verbs\n\t\t\tdelete this.#options.verbs\n\t\t}\n\n\t\tfor (const verb of this.#verbs) {\n\t\t\tthis[verb] = async function(...options) {\n\t\t\t\treturn this.fetch(request(\n\t\t\t\t\tthis.#options,\n\t\t\t\t\t...options,\n\t\t\t\t\t{method: verb.toUpperCase()}\n\t\t\t\t))\n\t\t\t}\n\t\t}\n\t\tObject.freeze(this)\n\t}\n\n\t#addMiddlewares(middlewares)\n\t{\n\t\tif (typeof middlewares == 'function') {\n\t\t\tmiddlewares = [ middlewares ]\n\t\t}\n\t\tlet index = middlewares.findIndex(m => typeof m != 'function')\n\t\tif (index>=0) {\n\t\t\tthrow metroError('metro.client: middlewares must be a function or an array of functions '\n\t\t\t\t+metroURL+'client/invalid-middlewares-value/', middlewares[index])\n\t\t}\n\t\tif (!Array.isArray(this.#options.middlewares)) {\n\t\t\tthis.#options.middlewares = []\n\t\t}\n\t\tthis.#options.middlewares = this.#options.middlewares.concat(middlewares)\n\t}\n\n\t/**\n\t * Mimics the standard browser fetch method, but uses any middleware installed through\n\t * the constructor.\n\t * @param {Request|string|Object} - Required. The URL or Request object, accepts all types that are accepted by metro.request\n\t * @param {Object} - Optional. Any object that is accepted by metro.request\n\t * @return {Promise} - The metro.response to this request, or any other result as changed by any included middleware.\n\t */\n\tfetch(req, options)\n\t{\n\t\treq = request(req, options)\n\t\tif (!req.url) {\n\t\t\tthrow metroError('metro.client.'+req.method.toLowerCase()+': Missing url parameter '+metroURL+'client/missing-url-param/', req)\n\t\t}\n\t\tif (!options) {\n\t\t\toptions = {}\n\t\t}\n\t\tif (!(typeof options === 'object') \n\t\t\t|| Array.isArray(options)\n\t\t\t|| options instanceof String) \n\t\t{\n\t\t\tthrow metroError('metro.client.fetch: Options is not an object')\n\t\t}\n\n\t\tconst metrofetch = async function browserFetch(req)\n\t\t{\n\t\t\tif (req[symbols.isProxy]) {\n\t\t\t\t// even though a Proxy is supposed to be 'invisible'\n\t\t\t\t// fetch() doesn't work with the proxy (in Firefox), \n\t\t\t\t// you need the actual Request object here\n\t\t\t\treq = req[symbols.source]\n\t\t\t}\n\t\t\tconst res = await fetch(req)\n\t\t\treturn response(res)\n\t\t}\n\t\t\n\t\tlet middlewares = [metrofetch].concat(this.#options?.middlewares?.slice() || [])\n\t\toptions = Object.assign({}, this.#options, options)\n\t\t//@TODO: do this once in constructor?\n\t\tlet next\n\t\tfor (let middleware of middlewares) {\n\t\t\tnext = (function(next, middleware) {\n\t\t\t\treturn async function(req) {\n\t\t\t\t\tlet res\n\t\t\t\t\tlet tracers = Object.values(Client.tracers)\n\t\t\t\t\tfor(let tracer of tracers) {\n\t\t\t\t\t\tif (tracer.request) {\n\t\t\t\t\t\t\ttracer.request.call(tracer, req, middleware)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tres = await middleware(req, next)\n\t\t\t\t\tfor(let tracer of tracers) {\n\t\t\t\t\t\tif (tracer.response) {\n\t\t\t\t\t\t\ttracer.response.call(tracer, res, middleware)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn res\n\t\t\t\t}\t\t\t\t\t\t\t\t\n\t\t\t})(next, middleware)\n\t\t}\n\t\treturn next(req)\n\t}\n\n\twith(...options) {\n\t\treturn new Client(this, ...options)\n\t}\n}\n\n/**\n * Returns a new metro Client object.\n * @param {...ClientOptions|string|URL}\n * @return Client\n */\nexport function client(...options)\n{\n\treturn new Client(...options)\n}\n\nfunction appendHeaders(r, headers)\n{\n\tif (!Array.isArray(headers)) {\n\t\theaders = [headers]\n\t}\n\theaders.forEach((header) => {\n\t\tif (typeof header == 'function') {\n\t\t\tlet result = header(r.headers, r)\n\t\t\tif (result) {\n\t\t\t\tif (!Array.isArray(result)) {\n\t\t\t\t\tresult = [result]\n\t\t\t\t}\n\t\t\t\theaders = headers.concat(result)\n\t\t\t}\n\t\t}\n\t})\n\theaders.forEach((header) => {\n\t\tObject.entries(header).forEach(([name,value]) => {\t\t\t\n\t\t\tr.headers.append(name, value)\n\t\t})\n\t})\n}\n\nfunction bodyProxy(body, r)\n{\n\tlet source = r.body\n\tif (!source) {\n\t\t//Firefox does not allow access to Request.body (undefined)\n\t\t//Chrome and Nodejs do, so mimic the correct (documented)\n\t\t//result here\n\t\tif (body === null) {\n\t\t\tsource = new ReadableStream()\n\t\t} else if (body instanceof ReadableStream) {\n\t\t\tsource = body\n\t\t} else if (body instanceof Blob) {\n\t\t\tsource = body.stream()\n\t\t} else {\n\t\t\tsource = new ReadableStream({\n\t\t\t\tstart(controller) {\n\t\t\t\t\tlet chunk\n\t\t\t\t\tswitch(typeof body) {\n\t\t\t\t\t\tcase 'object':\n\t\t\t\t\t\t\tif (typeof body.toString == 'function') {\n\t\t\t\t\t\t\t\t// also catches URLSearchParams\n\t\t\t\t\t\t\t\tchunk = body.toString()\n\t\t\t\t\t\t\t} else if (body instanceof FormData) {\n\t\t\t\t\t\t\t\tchunk = new URLSearchParams(body).toString()\n\t\t\t\t\t\t\t} else if (body instanceof ArrayBuffer\n\t\t\t\t\t\t\t\t|| ArrayBuffer.isView(body)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t// catchs TypedArrays - e.g. Uint16Array\n\t\t\t\t\t\t\t\tchunk = body\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthrow metroError('Cannot convert body to ReadableStream', body)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'string':\n\t\t\t\t\t\tcase 'number':\n\t\t\t\t\t\tcase 'boolean':\n\t\t\t\t\t\t\tchunk = body\n\t\t\t\t\t\tbreak\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow metroError('Cannot convert body to ReadableStream', body)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcontroller.enqueue(chunk)\n\t\t\t\t\tcontroller.close()\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\treturn new Proxy(source, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch (prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn body\n\t\t\t\tbreak\n\t\t\t\tcase 'toString':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn ''+body\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (typeof body == 'object') {\n\t\t\t\tif (prop in body) {\n\t\t\t\t\tif (typeof body[prop] == 'function') {\n\t\t\t\t\t\treturn function(...args) {\n\t\t\t\t\t\t\treturn body[prop].apply(body, args)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn body[prop]\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (prop in target && prop != 'toString') {\n\t\t\t\t// skipped toString, since it has no usable output\n\t\t\t\t// and body may have its own toString\n\t\t\t\tif (typeof target[prop] == 'function') {\n\t\t\t\t\treturn function(...args) {\n\t\t\t\t\t\treturn target[prop].apply(target, args)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn target[prop]\n\t\t\t}\n\t\t},\n\t\thas(target, prop) {\n\t\t\treturn prop in body\n\t\t},\n\t\townKeys(target) {\n\t\t\treturn Reflect.ownKeys(body)\n\t\t},\n\t\tgetOwnPropertyDescriptor(target, prop) {\n\t\t\treturn Object.getOwnPropertyDescriptor(body,prop)\n\t\t}\n\t})\n}\n\nfunction getRequestParams(req, current)\n{\n\tlet params = current || {}\n\tif (!params.url && current.url) {\n\t\tparams.url = current.url\n\t}\n\t// function to fetch all relevant properties of a Request\n\tfor(let prop of ['method','headers','body','mode','credentials','cache','redirect',\n\t\t'referrer','referrerPolicy','integrity','keepalive','signal',\n\t\t'priority','url']) {\n\t\tif (typeof req[prop] == 'function') {\n\t\t\treq[prop](params[prop], params)\n\t\t} else if (typeof req[prop] != 'undefined') {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = url(params.url, req.url)\n\t\t\t} else if (prop == 'headers') {\n\t\t\t\tparams.headers = new Headers(current.headers)\n\t\t\t\tif (!(req.headers instanceof Headers)) {\n\t\t\t\t\treq.headers = new Headers(req.headers)\n\t\t\t\t}\n\t\t\t\tfor (let [key, value] of req.headers.entries()) {\n\t\t\t\t\tparams.headers.set(key, value)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparams[prop] = req[prop]\n\t\t\t}\n\t\t}\n\t}\n\treturn params\n}\n\n/**\n * @typedef {Request} MetroRequest\n * @property {Symbol(source)} - returns the target Request of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroRequest, with the given options added\n * @param {} ...options - request options, handled in order\n * \n * Returns a new metro Request object\n * @param {} ...options - request options, handled in order\n * @return {MetroRequest} - a new metro Request object\n */\nexport function request(...options)\n{\n\t// the standard Request constructor is a minefield\n\t// so first gather all the options together into a single\n\t// javascript object, then set it in one go\n\tlet requestParams = {\n\t\turl: typeof window != 'undefined' ? window.location : 'https://localhost/',\n\t\tduplex: 'half' // required when setting body to ReadableStream, just set it here by default already\n\t}\n\tfor (let option of options) {\n\t\tif (typeof option == 'string'\n\t\t\t|| option instanceof URL\n\t\t\t|| option instanceof URLSearchParams\n\t\t) {\n\t\t\trequestParams.url = url(requestParams.url, option)\n\t\t} else if (option && (\n\t\t\toption instanceof FormData\n\t\t\t|| option instanceof ReadableStream\n\t\t\t|| option instanceof Blob\n\t\t\t|| option instanceof ArrayBuffer\n\t\t\t|| option instanceof DataView\n\t\t)) {\n\t\t\trequestParams.body = option\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tObject.assign(requestParams, getRequestParams(option, requestParams))\n\t\t}\n\t}\n\tlet body = requestParams.body\n\tif (body) {\n\t\tif (typeof body == 'object'\n\t\t\t&& !(body instanceof String)\n\t\t\t&& !(body instanceof ReadableStream)\n\t\t\t&& !(body instanceof Blob)\n\t\t\t&& !(body instanceof ArrayBuffer)\n\t\t\t&& !(body instanceof DataView)\n\t\t\t&& !(body instanceof FormData)\n\t\t\t&& !(body instanceof URLSearchParams)\n\t\t\t&& (typeof TypedArray=='undefined' || !(body instanceof TypedArray))\n\t\t) {\n\t\t\trequestParams.body = JSON.stringify(body)\n\t\t}\n\t}\n\tlet r = new Request(requestParams.url, requestParams)\n\tObject.freeze(r)\n\treturn new Proxy(r, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\tif (body) { // body is kept in a seperate value, if it set earlier\n\t\t\t\t\t\t\toptions.unshift({ body }) // unshifted so it can be overridden by options\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn request(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'toString':\n\t\t\t\tcase 'toJSON':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn target[prop].apply(target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'blob':\n\t\t\t\tcase 'text':\n\t\t\t\tcase 'json':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn target[prop].apply(target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'body':\n\t\t\t\t\t// Request.body is always a ReadableStream\n\t\t\t\t\t// which is a horrible API, if you want to\n\t\t\t\t\t// allow middleware to alter the body\n\t\t\t\t\t// so we keep the original body, wrap a Proxy\n\t\t\t\t\t// around it to keep the ReadableStream api\n\t\t\t\t\t// accessible, but allow access to the original\n\t\t\t\t\t// body value as well\n\t\t\t\t\tif (!body) {\n\t\t\t\t\t\tbody = target.body\n\t\t\t\t\t}\n\t\t\t\t\tif (body) {\n\t\t\t\t\t\tif (body[symbols.isProxy]) {\n\t\t\t\t\t\t\treturn body\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn bodyProxy(body, target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn target[prop]\n\t\t}\n\t})\n}\n\nfunction getResponseParams(res, current)\n{\n\t// function to fetch all relevant properties of a Response\n\tlet params = current || {}\n\tif (!params.url && current.url) {\n\t\tparams.url = current.url\n\t}\n\tfor(let prop of ['status','statusText','headers','body','url','type','redirected']) {\n\t\tif (typeof res[prop] == 'function') {\n\t\t\tres[prop](params[prop], params)\n\t\t} else if (typeof res[prop] != 'undefined') {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = new URL(res.url, params.url || 'https://localhost/')\n\t\t\t} else {\n\t\t\t\tparams[prop] = res[prop]\n\t\t\t}\n\t\t}\n\t}\n\treturn params\n}\n\n/**\n * @typedef {Response} MetroResponse\n * @property {Symbol(source)} - returns the target Response of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroResponse, with the given options added\n * @param {} ...options - respomse options, handled in order\n * \n * Returns a new metro Response object\n * @param {} ...options - request options, handled in order\n * @return {MetroResponse} - a new metro Response object\n */\nexport function response(...options)\n{\n\tlet responseParams = {}\n\tfor (let option of options) {\n\t\tif (typeof option == 'string') {\n\t\t\tresponseParams.body = option\n\t\t} else if (option instanceof Response) {\n\t\t\tObject.assign(responseParams, getResponseParams(option, responseParams))\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tif (option instanceof FormData\n\t\t\t\t|| option instanceof Blob\n\t\t\t\t|| option instanceof ArrayBuffer\n\t\t\t\t|| option instanceof DataView\n\t\t\t\t|| option instanceof ReadableStream\n\t\t\t\t|| option instanceof URLSearchParams\n\t\t\t\t|| option instanceof String\n\t\t\t\t|| (typeof TypedArray != 'undefined' && option instanceof TypedArray)\n\t\t\t) {\n\t\t\t\tresponseParams.body = option\n\t\t\t} else {\n\t\t\t\tObject.assign(responseParams, getResponseParams(option, responseParams))\n\t\t\t}\n\t\t}\n\t}\n\tlet r = new Response(responseParams.body, responseParams)\t\n\tObject.freeze(r)\n\treturn new Proxy(r, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\treturn response(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'body':\n\t\t\t\t\tif (responseParams.body) {\n\t\t\t\t\t\tif (responseParams.body[symbols.isProxy]) {\n\t\t\t\t\t\t\treturn responseParams.body\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn bodyProxy(responseParams.body, target)\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn bodyProxy('',target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'ok':\n\t\t\t\t\treturn (target.status>=200) && (target.status<400)\n\t\t\t\tbreak\n\t\t\t\tcase 'headers':\n\t\t\t\t\treturn target.headers\n\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\tif (prop in responseParams && prop != 'toString') {\n\t\t\t\t\t\treturn responseParams[prop]\n\t\t\t\t\t}\n\t\t\t\t\tif (prop in target && prop != 'toString') {\n\t\t\t\t\t\t// skipped toString, since it has no usable output\n\t\t\t\t\t\t// and body may have its own toString\n\t\t\t\t\t\tif (typeof target[prop] == 'function') {\n\t\t\t\t\t\t\treturn function(...args) {\n\t\t\t\t\t\t\t\treturn target[prop].apply(target, args)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn target[prop]\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn undefined\n\t\t}\n\t})\n}\n\nfunction appendSearchParams(url, params) {\n\tif (typeof params == 'function') {\n\t\t params(url.searchParams, url)\n\t} else {\n\t\tparams = new URLSearchParams(params)\n\t\tparams.forEach((value,key) => {\n\t\t\turl.searchParams.append(key, value)\n\t\t})\n\t}\n}\n\n/**\n * @typedef {URL} MetroURL\n * @property {Symbol(source)} - returns the target Request of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroRequest, with the given options added\n * @param {} ...options - url options, handled in order\n * \n * Returns a new metro URL object\n * @param {} ...options - url options, handled in order\n * @return {MetroURL} - a new metro URL object\n */\nexport function url(...options)\n{\n\tlet validParams = ['hash','host','hostname','href',\n\t\t\t'password','pathname','port','protocol','username','search','searchParams']\n\tlet u = new URL('https://localhost/')\n\tfor (let option of options) {\n\t\tif (typeof option == 'string' || option instanceof String) {\n\t\t\t// option is a relative or absolute url\n\t\t\tu = new URL(option, u)\n\t\t} else if (option instanceof URL \n\t\t\t|| (typeof Location != 'undefined' \n\t\t\t\t&& option instanceof Location)\n\t\t) {\n\t\t\tu = new URL(option)\n\t\t} else if (option instanceof URLSearchParams) {\n\t\t\tappendSearchParams(u, option)\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tfor (let param in option) {\n\t\t\t\tif (param=='search') {\n\t\t\t\t\tif (typeof option.search == 'function') {\n\t\t\t\t\t\toption.search(u.search, u)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tu.search = new URLSearchParams(option.search)\n\t\t\t\t\t}\n\t\t\t\t} else if (param=='searchParams') {\n\t\t\t\t\tappendSearchParams(u, option.searchParams)\n\t\t\t\t} else {\n\t\t\t\t\tif (!validParams.includes(param)) {\n\t\t\t\t\t\tthrow metroError('metro.url: unknown url parameter '+metroURL+'url/unknown-param-name/', param)\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof option[param] == 'function') {\n\t\t\t\t\t\toption[param](u[param], u)\n\t\t\t\t\t} else if (\n\t\t\t\t\t\ttypeof option[param] == 'string' || option[param] instanceof String \n\t\t\t\t\t\t|| typeof option[param] == 'number' || option[param] instanceof Number\n\t\t\t\t\t\t|| typeof option[param] == 'boolean' || option[param] instanceof Boolean\n\t\t\t\t\t) {\n\t\t\t\t\t\tu[param] = ''+option[param]\n\t\t\t\t\t} else if (typeof option[param] == 'object' && option[param].toString) {\n\t\t\t\t\t\tu[param] = option[param].toString()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow metroError('metro.url: unsupported value for '+param+' '+metroURL+'url/unsupported-param-value/', options[param])\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow metroError('metro.url: unsupported option value '+metroURL+'url/unsupported-option-value/', option)\n\t\t}\n\t}\n\tObject.freeze(u)\n\treturn new Proxy(u, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\treturn url(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'toString':\n\t\t\t\tcase 'toJSON':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn target[prop]()\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn target[prop]\n\t\t}\n\t})\n}\n\n/**\n * @typedef {FormData} MetroFormData\n * @property {Symbol(source)} - returns the target Request of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroRequest, with the given options added\n * @param {} ...options - url options, handled in order\n * \n * Returns a new metro FormData object\n * @param {} ...options - formdata options, handled in order\n * @return {MetroURL} - a new metro FormData object\n */\nexport function formdata(...options)\n{\n\tvar params = new FormData()\n\tfor (let option of options) {\n\t\tif (option instanceof FormData) {\n\t\t\tfor (let entry of option.entries()) {\n\t\t\t\tparams.append(entry[0],entry[1])\n\t\t\t}\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tfor (let entry of Object.entries(option)) {\n\t\t\t\tif (Array.isArray(entry[1])) {\n\t\t\t\t\tfor (let value of entry[1]) {\n\t\t\t\t\t\tparams.append(entry[0], value)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tparams.append(entry[0],entry[1])\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new metroError('metro.formdata: unknown option type, only FormData or Object supported',option)\n\t\t}\n\t}\n\tObject.freeze(params)\n\treturn new Proxy(params, {\n\t\tget: (target,prop,receiver) => {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\treturn formdata(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\t// case 'toString':\n\t\t\t\t// case 'toJSON':\n\t\t\t\t// \treturn function() {\n\t\t\t\t// \t\treturn target[prop]()\n\t\t\t\t// \t}\n\t\t\t\t// break\n\t\t\t}\n\t\t\treturn target[prop]\n\t\t}\n\t})\n}\n\nconst metroConsole = {\n\terror: (message, ...details) => {\n\t\tconsole.error('Ⓜ️ ',message, ...details)\n\t},\n\tinfo: (message, ...details) => {\n\t\tconsole.info('Ⓜ️ ',message, ...details)\n\t},\n\tgroup: (name) => {\n\t\tconsole.group('Ⓜ️ '+name)\n\t},\n\tgroupEnd: (name) => {\n\t\tconsole.groupEnd('Ⓜ️ '+name)\n\t}\n}\n\n\n/**\n * Custom Metro Error function that outputs to the console then throws an error\n */\nexport function metroError(message, ...details) {\n\tmetroConsole.error(message, ...details)\n\treturn new Error(message, ...details)\n}\n\n/**\n * Set of debugging tools to trace the request - response flow\n * Tracer are run on all metro fetch calls\n */\nexport const trace = {\n\t/**\n\t * Adds a named tracer function\n\t * @param {string} name - the name of the tracer\n\t * @param {Function} tracer - the tracer function to call\n\t */\n\tadd(name, tracer) {\n\t\tClient.tracers[name] = tracer\n\t},\n\t/**\n\t * Removes a named tracer function\n\t * @param {string} name\n\t */\n\tdelete(name) {\n\t\tdelete Client.tracers[name]\n\t},\n\t/**\n\t * Removes all tracer functions\n\t */\n\tclear() {\n\t\tClient.tracers = {}\n\t},\n\t/**\n\t * Returns a set of request and response tracer functions that use the\n\t * console.group feature to shows nested request/response pairs, with\n\t * most commonly needed information for debugging\n\t */\n\tgroup() {\n\t\tlet group = 0;\n\t\treturn {\n\t\t\trequest: (req, middleware) => {\n\t\t\t\tgroup++\n\t\t\t\tmetroConsole.group(group)\n\t\t\t\tmetroConsole.info(req?.url, req, middleware)\n\t\t\t},\n\t\t\tresponse: (res, middleware) => {\n\t\t\t\tmetroConsole.info(res?.body ? res.body[symbols.source]: null, res, middleware)\n\t\t\t\tmetroConsole.groupEnd(group)\n\t\t\t\tgroup--\n\t\t\t}\n\t\t}\n\t}\n}\n","import * as metro from './metro.mjs'\n\nwindow.metro = metro\n"],"names":["$parcel$export","e","n","v","s","Object","defineProperty","get","set","enumerable","configurable","$parcel$global","globalThis","$parcel$modules","$parcel$inits","parcelRequire","id","exports","init","module","call","err","Error","code","register","parcelRegister","$86c8ab3a59b0bae1$export$47616e9f7f5fe113","$86c8ab3a59b0bae1$export$b5fe3f66a567bec0","$86c8ab3a59b0bae1$export$7079e2c78c274c66","$86c8ab3a59b0bae1$export$785bb8ef7fad1f74","$86c8ab3a59b0bae1$export$388e0302ca0d9a41","$86c8ab3a59b0bae1$export$128fa18b7194ef","$86c8ab3a59b0bae1$export$5de500aade6bf050","options","params","FormData","option","entry","entries","append","Array","isArray","value","freeze","Proxy","target","prop","receiver","isProxy","source","$86c8ab3a59b0bae1$export$357889f174732d38","$86c8ab3a59b0bae1$var$metroURL","Symbol","$86c8ab3a59b0bae1$var$Client","url","window","location","tracers","constructor","String","assign","Function","param","verb","verbs","fetch","method","toUpperCase","middlewares","index","findIndex","m","concat","req","next","toLowerCase","slice","middleware","res","values","tracer","request","response","with","$86c8ab3a59b0bae1$var$bodyProxy","body","r","ReadableStream","Blob","stream","start","controller","chunk","toString","URLSearchParams","ArrayBuffer","isView","enqueue","close","args","apply","has","ownKeys","Reflect","getOwnPropertyDescriptor","requestParams","duplex","URL","DataView","$86c8ab3a59b0bae1$var$getRequestParams","current","key","headers","Headers","TypedArray","JSON","stringify","Request","unshift","$86c8ab3a59b0bae1$var$getResponseParams","responseParams","Response","status","$86c8ab3a59b0bae1$var$appendSearchParams","searchParams","forEach","validParams","u","Location","search","includes","Number","Boolean","message","details","console","error","info","name","group","groupEnd","$86c8ab3a59b0bae1$var$metroConsole","add","delete","clear","$hkeot","metro"],"version":3,"file":"browser.js.map","sourceRoot":"../"} \ No newline at end of file diff --git a/dist/everything.js b/dist/everything.js index bce4065..b52bc8a 100644 --- a/dist/everything.js +++ b/dist/everything.js @@ -1,2 +1,2 @@ -function e(e,t,r,o){Object.defineProperty(e,t,{get:r,set:o,enumerable:!0,configurable:!0})}var t=globalThis,r={},o={},n=t.parcelRequireea2c;null==n&&((n=function(e){if(e in r)return r[e].exports;if(e in o){var t=o[e];delete o[e];var n={id:e,exports:{}};return r[e]=n,t.call(n.exports,n,n.exports),n.exports}var s=Error("Cannot find module '"+e+"'");throw s.code="MODULE_NOT_FOUND",s}).register=function(e,t){o[e]=t},t.parcelRequireea2c=n),(0,n.register)("hkeot",function(t,r){e(t.exports,"symbols",()=>n),e(t.exports,"request",()=>c),e(t.exports,"metroError",()=>w),e(t.exports,"response",()=>u),e(t.exports,"client",()=>a),e(t.exports,"url",()=>p),e(t.exports,"formdata",()=>function e(...t){var r=new FormData;for(let e of t)if(e instanceof FormData)for(let t of e.entries())r.append(t[0],t[1]);else if(e&&"object"==typeof e)for(let t of Object.entries(e))if(Array.isArray(t[1]))for(let e of t[1])r.append(t[0],e);else r.append(t[0],t[1]);else throw new w("metro.formdata: unknown option type, only FormData or Object supported",e);return Object.freeze(r),new Proxy(r,{get:(t,r,o)=>{switch(r){case n.isProxy:return!0;case n.source:return t;case"with":return function(...r){return e(t,...r)};case"toString":case"toJSON":return function(){return t[r]()}}return t[r]}})}),e(t.exports,"trace",()=>m);let o="https://metro.muze.nl/details/",n={isProxy:Symbol("isProxy"),source:Symbol("source")};class s{#e={url:"undefined"!=typeof window?window.location:"https://localhost"};#t=["get","post","put","delete","patch","head","options","query"];static tracers={};constructor(...e){for(let t of e)if("string"==typeof t||t instanceof String)this.#e.url=""+t;else if(t instanceof s)Object.assign(this.#e,t.#e);else if(t instanceof Function)this.#r([t]);else if(t&&"object"==typeof t)for(let e in t)"middlewares"==e?this.#r(t[e]):"function"==typeof t[e]?this.#e[e]=t[e](this.#e[e],this.#e):this.#e[e]=t[e];for(let e of(this.#e.verbs&&(this.#t=this.#e.verbs,delete this.#e.verbs),this.#t))this[e]=async function(...t){return this.fetch(c(this.#e,...t,{method:e.toUpperCase()}))};Object.freeze(this)}#r(e){"function"==typeof e&&(e=[e]);let t=e.findIndex(e=>"function"!=typeof e);if(t>=0)throw w("metro.client: middlewares must be a function or an array of functions "+o+"client/invalid-middlewares-value/",e[t]);Array.isArray(this.#e.middlewares)||(this.#e.middlewares=[]),this.#e.middlewares=this.#e.middlewares.concat(e)}fetch(e,t){let r;if(!(e=c(e,t)).url)throw w("metro.client."+e.method.toLowerCase()+": Missing url parameter "+o+"client/missing-url-param/",e);if(t||(t={}),"object"!=typeof t||Array.isArray(t)||t instanceof String)throw w("metro.client.fetch: Options is not an object");let a=[async function(e){return e[n.isProxy]&&(e=e[n.source]),u(await fetch(e))}].concat(this.#e?.middlewares?.slice()||[]);for(let e of(t=Object.assign({},this.#e,t),a))r=function(e,t){return async function(r){let o;let n=Object.values(s.tracers);for(let e of n)e.request&&e.request.call(e,r,t);for(let s of(o=await t(r,e),n))s.response&&s.response.call(s,o,t);return o}}(r,e);return r(e)}with(...e){return new s(this,...e)}}function a(...e){return new s(...e)}function i(e,t){let r=t.body;return r||(null===e?r=new ReadableStream:e instanceof ReadableStream?r=e:e instanceof Blob?r=e.stream():r=new ReadableStream({start(t){let r;switch(typeof e){case"object":if("function"==typeof e.toString)r=e.toString();else if(e instanceof FormData)r=new URLSearchParams(e).toString();else if(e instanceof ArrayBuffer||ArrayBuffer.isView(e))r=e;else throw w("Cannot convert body to ReadableStream",e);break;case"string":case"number":case"boolean":r=e;break;default:throw w("Cannot convert body to ReadableStream",e)}t.enqueue(r),t.close()}})),new Proxy(r,{get(t,r,o){switch(r){case n.isProxy:return!0;case n.source:return e;case"toString":return function(){return""+e}}return"object"==typeof e&&r in e?"function"==typeof e[r]?function(...t){return e[r].apply(e,t)}:e[r]:r in t&&"toString"!=r?"function"==typeof t[r]?function(...e){return t[r].apply(t,e)}:t[r]:void 0},has:(t,r)=>r in e,ownKeys:t=>Reflect.ownKeys(e),getOwnPropertyDescriptor:(t,r)=>Object.getOwnPropertyDescriptor(e,r)})}function c(...e){let t={url:"undefined"!=typeof window?window.location:"https://localhost/",duplex:"half"};for(let r of e)"string"==typeof r||r instanceof URL||r instanceof URLSearchParams?t.url=p(t.url,r):r&&(r instanceof FormData||r instanceof ReadableStream||r instanceof Blob||r instanceof ArrayBuffer||r instanceof DataView)?t.body=r:r&&"object"==typeof r&&Object.assign(t,function(e,t){let r=t||{};for(let o of(!r.url&&t.url&&(r.url=t.url),["method","headers","body","mode","credentials","cache","redirect","referrer","referrerPolicy","integrity","keepalive","signal","priority","url"]))if("function"==typeof e[o])e[o](r[o],r);else if(void 0!==e[o]){if("url"==o)r.url=p(r.url,e.url);else if("headers"==o)for(let[o,n]of(r.headers=new Headers(t.headers),e.headers instanceof Headers||(e.headers=new Headers(e.headers)),e.headers.entries()))r.headers.set(o,n);else r[o]=e[o]}return r}(r,t));let r=t.body;!r||"object"!=typeof r||r instanceof String||r instanceof ReadableStream||r instanceof Blob||r instanceof ArrayBuffer||r instanceof DataView||r instanceof FormData||r instanceof URLSearchParams||"undefined"!=typeof TypedArray&&r instanceof TypedArray||(t.body=JSON.stringify(r));let o=new Request(t.url,t);return Object.freeze(o),new Proxy(o,{get(e,t,o){switch(t){case n.source:return e;case n.isProxy:return!0;case"with":return function(...t){return r&&t.unshift({body:r}),c(e,...t)};case"toString":case"toJSON":case"blob":case"text":case"json":return function(){return e[t].apply(e)};case"body":if(r||(r=e.body),r){if(r[n.isProxy])return r;return i(r,e)}}return e[t]}})}function f(e,t){let r=t||{};for(let o of(!r.url&&t.url&&(r.url=t.url),["status","statusText","headers","body","url","type","redirected"]))"function"==typeof e[o]?e[o](r[o],r):void 0!==e[o]&&("url"==o?r.url=new URL(e.url,r.url||"https://localhost/"):r[o]=e[o]);return r}function u(...e){let t={};for(let r of e)"string"==typeof r?t.body=r:r instanceof Response?Object.assign(t,f(r,t)):r&&"object"==typeof r&&(r instanceof FormData||r instanceof Blob||r instanceof ArrayBuffer||r instanceof DataView||r instanceof ReadableStream||r instanceof URLSearchParams||r instanceof String||"undefined"!=typeof TypedArray&&r instanceof TypedArray?t.body=r:Object.assign(t,f(r,t)));let r=new Response(t.body,t);return Object.freeze(r),new Proxy(r,{get(e,r,o){switch(r){case n.isProxy:return!0;case n.source:return e;case"with":return function(...t){return u(e,...t)};case"body":if(!t.body)return i("",e);if(t.body[n.isProxy])return t.body;return i(t.body,e);case"ok":return e.status>=200&&e.status<400;case"headers":return e.headers;default:if(r in t&&"toString"!=r)return t[r];if(r in e&&"toString"!=r){if("function"==typeof e[r])return function(...t){return e[r].apply(e,t)};return e[r]}}}})}function l(e,t){"function"==typeof t?t(e.searchParams,e):(t=new URLSearchParams(t)).forEach((t,r)=>{e.searchParams.append(r,t)})}function p(...e){let t=["hash","host","hostname","href","password","pathname","port","protocol","username","search","searchParams"],r=new URL("https://localhost/");for(let n of e)if("string"==typeof n||n instanceof String)r=new URL(n,r);else if(n instanceof URL||"undefined"!=typeof Location&&n instanceof Location)r=new URL(n);else if(n instanceof URLSearchParams)l(r,n);else if(n&&"object"==typeof n)for(let s in n)if("search"==s)"function"==typeof n.search?n.search(r.search,r):r.search=new URLSearchParams(n.search);else if("searchParams"==s)l(r,n.searchParams);else{if(!t.includes(s))throw w("metro.url: unknown url parameter "+o+"url/unknown-param-name/",s);if("function"==typeof n[s])n[s](r[s],r);else if("string"==typeof n[s]||n[s]instanceof String||"number"==typeof n[s]||n[s]instanceof Number||"boolean"==typeof n[s]||n[s]instanceof Boolean)r[s]=""+n[s];else if("object"==typeof n[s]&&n[s].toString)r[s]=n[s].toString();else throw w("metro.url: unsupported value for "+s+" "+o+"url/unsupported-param-value/",e[s])}else throw w("metro.url: unsupported option value "+o+"url/unsupported-option-value/",n);return Object.freeze(r),new Proxy(r,{get(e,t,r){switch(t){case n.isProxy:return!0;case n.source:return e;case"with":return function(...t){return p(e,...t)};case"toString":case"toJSON":return function(){return e[t]()}}return e[t]}})}let d=(e,...t)=>{console.error("Ⓜ️ ",e,...t)},y=(e,...t)=>{console.info("Ⓜ️ ",e,...t)},h=e=>{console.group("Ⓜ️ "+e)},b=e=>{console.groupEnd("Ⓜ️ "+e)};function w(e,...t){return d(e,...t),Error(e,...t)}let m={add(e,t){s.tracers[e]=t},delete(e){delete s.tracers[e]},clear(){s.tracers={}},group(){let e=0;return{request:(t,r)=>{h(++e),y(t?.url,t,r)},response:(t,r)=>{y(t?.body?t.body[n.source]:null,t,r),b(e),e--}}}}});var s=(n("hkeot"),n("hkeot"));n("hkeot"),window.metro=Object.assign({},s,{mw:{jsonmw:function(e){return e=Object.assign({reviver:null,replacer:null,space:""},e),async(t,r)=>{["POST","PUT","PATCH","QUERY"].includes(t.method)?(t=t.with({headers:{"Content-Type":"application/json",Accept:"application/json"}})).body&&"object"==typeof t.body[s.symbols.source]&&(t=t.with({body:JSON.stringify(t.body[s.symbols.source],e.replacer,e.space)})):t=t.with({headers:{Accept:"application/json"}});let o=await r(t),n=JSON.parse(await o.text(),e.reviver);return o.with({body:n})}},thrower:function(e){return async(t,r)=>{let o=await r(t);if(!o.ok){if(e&&"function"==typeof e[o.status])o=e[o.status].apply(o,t);else throw Error(o.status+": "+o.statusText,{cause:o})}return o}}}}); +function e(e,t,r,o){Object.defineProperty(e,t,{get:r,set:o,enumerable:!0,configurable:!0})}var t=globalThis,r={},o={},n=t.parcelRequire94c2;null==n&&((n=function(e){if(e in r)return r[e].exports;if(e in o){var t=o[e];delete o[e];var n={id:e,exports:{}};return r[e]=n,t.call(n.exports,n,n.exports),n.exports}var s=Error("Cannot find module '"+e+"'");throw s.code="MODULE_NOT_FOUND",s}).register=function(e,t){o[e]=t},t.parcelRequire94c2=n),(0,n.register)("hkeot",function(t,r){e(t.exports,"symbols",()=>n),e(t.exports,"request",()=>c),e(t.exports,"metroError",()=>w),e(t.exports,"response",()=>u),e(t.exports,"client",()=>a),e(t.exports,"url",()=>p),e(t.exports,"formdata",()=>function e(...t){var r=new FormData;for(let e of t)if(e instanceof FormData)for(let t of e.entries())r.append(t[0],t[1]);else if(e&&"object"==typeof e)for(let t of Object.entries(e))if(Array.isArray(t[1]))for(let e of t[1])r.append(t[0],e);else r.append(t[0],t[1]);else throw new w("metro.formdata: unknown option type, only FormData or Object supported",e);return Object.freeze(r),new Proxy(r,{get:(t,r,o)=>{switch(r){case n.isProxy:return!0;case n.source:return t;case"with":return function(...r){return e(t,...r)}}return t[r]}})}),e(t.exports,"trace",()=>m);let o="https://metro.muze.nl/details/",n={isProxy:Symbol("isProxy"),source:Symbol("source")};class s{#e={url:"undefined"!=typeof window?window.location:"https://localhost"};#t=["get","post","put","delete","patch","head","options","query"];static tracers={};constructor(...e){for(let t of e)if("string"==typeof t||t instanceof String)this.#e.url=""+t;else if(t instanceof s)Object.assign(this.#e,t.#e);else if(t instanceof Function)this.#r([t]);else if(t&&"object"==typeof t)for(let e in t)"middlewares"==e?this.#r(t[e]):"function"==typeof t[e]?this.#e[e]=t[e](this.#e[e],this.#e):this.#e[e]=t[e];for(let e of(this.#e.verbs&&(this.#t=this.#e.verbs,delete this.#e.verbs),this.#t))this[e]=async function(...t){return this.fetch(c(this.#e,...t,{method:e.toUpperCase()}))};Object.freeze(this)}#r(e){"function"==typeof e&&(e=[e]);let t=e.findIndex(e=>"function"!=typeof e);if(t>=0)throw w("metro.client: middlewares must be a function or an array of functions "+o+"client/invalid-middlewares-value/",e[t]);Array.isArray(this.#e.middlewares)||(this.#e.middlewares=[]),this.#e.middlewares=this.#e.middlewares.concat(e)}fetch(e,t){let r;if(!(e=c(e,t)).url)throw w("metro.client."+e.method.toLowerCase()+": Missing url parameter "+o+"client/missing-url-param/",e);if(t||(t={}),"object"!=typeof t||Array.isArray(t)||t instanceof String)throw w("metro.client.fetch: Options is not an object");let a=[async function(e){return e[n.isProxy]&&(e=e[n.source]),u(await fetch(e))}].concat(this.#e?.middlewares?.slice()||[]);for(let e of(t=Object.assign({},this.#e,t),a))r=function(e,t){return async function(r){let o;let n=Object.values(s.tracers);for(let e of n)e.request&&e.request.call(e,r,t);for(let s of(o=await t(r,e),n))s.response&&s.response.call(s,o,t);return o}}(r,e);return r(e)}with(...e){return new s(this,...e)}}function a(...e){return new s(...e)}function i(e,t){let r=t.body;return r||(null===e?r=new ReadableStream:e instanceof ReadableStream?r=e:e instanceof Blob?r=e.stream():r=new ReadableStream({start(t){let r;switch(typeof e){case"object":if("function"==typeof e.toString)r=e.toString();else if(e instanceof FormData)r=new URLSearchParams(e).toString();else if(e instanceof ArrayBuffer||ArrayBuffer.isView(e))r=e;else throw w("Cannot convert body to ReadableStream",e);break;case"string":case"number":case"boolean":r=e;break;default:throw w("Cannot convert body to ReadableStream",e)}t.enqueue(r),t.close()}})),new Proxy(r,{get(t,r,o){switch(r){case n.isProxy:return!0;case n.source:return e;case"toString":return function(){return""+e}}return"object"==typeof e&&r in e?"function"==typeof e[r]?function(...t){return e[r].apply(e,t)}:e[r]:r in t&&"toString"!=r?"function"==typeof t[r]?function(...e){return t[r].apply(t,e)}:t[r]:void 0},has:(t,r)=>r in e,ownKeys:t=>Reflect.ownKeys(e),getOwnPropertyDescriptor:(t,r)=>Object.getOwnPropertyDescriptor(e,r)})}function c(...e){let t={url:"undefined"!=typeof window?window.location:"https://localhost/",duplex:"half"};for(let r of e)"string"==typeof r||r instanceof URL||r instanceof URLSearchParams?t.url=p(t.url,r):r&&(r instanceof FormData||r instanceof ReadableStream||r instanceof Blob||r instanceof ArrayBuffer||r instanceof DataView)?t.body=r:r&&"object"==typeof r&&Object.assign(t,function(e,t){let r=t||{};for(let o of(!r.url&&t.url&&(r.url=t.url),["method","headers","body","mode","credentials","cache","redirect","referrer","referrerPolicy","integrity","keepalive","signal","priority","url"]))if("function"==typeof e[o])e[o](r[o],r);else if(void 0!==e[o]){if("url"==o)r.url=p(r.url,e.url);else if("headers"==o)for(let[o,n]of(r.headers=new Headers(t.headers),e.headers instanceof Headers||(e.headers=new Headers(e.headers)),e.headers.entries()))r.headers.set(o,n);else r[o]=e[o]}return r}(r,t));let r=t.body;!r||"object"!=typeof r||r instanceof String||r instanceof ReadableStream||r instanceof Blob||r instanceof ArrayBuffer||r instanceof DataView||r instanceof FormData||r instanceof URLSearchParams||"undefined"!=typeof TypedArray&&r instanceof TypedArray||(t.body=JSON.stringify(r));let o=new Request(t.url,t);return Object.freeze(o),new Proxy(o,{get(e,t,o){switch(t){case n.source:return e;case n.isProxy:return!0;case"with":return function(...t){return r&&t.unshift({body:r}),c(e,...t)};case"toString":case"toJSON":return function(){return e[t].apply(e)};case"blob":case"text":case"json":return function(){return e[t].apply(e)};case"body":if(r||(r=e.body),r){if(r[n.isProxy])return r;return i(r,e)}}return e[t]}})}function f(e,t){let r=t||{};for(let o of(!r.url&&t.url&&(r.url=t.url),["status","statusText","headers","body","url","type","redirected"]))"function"==typeof e[o]?e[o](r[o],r):void 0!==e[o]&&("url"==o?r.url=new URL(e.url,r.url||"https://localhost/"):r[o]=e[o]);return r}function u(...e){let t={};for(let r of e)"string"==typeof r?t.body=r:r instanceof Response?Object.assign(t,f(r,t)):r&&"object"==typeof r&&(r instanceof FormData||r instanceof Blob||r instanceof ArrayBuffer||r instanceof DataView||r instanceof ReadableStream||r instanceof URLSearchParams||r instanceof String||"undefined"!=typeof TypedArray&&r instanceof TypedArray?t.body=r:Object.assign(t,f(r,t)));let r=new Response(t.body,t);return Object.freeze(r),new Proxy(r,{get(e,r,o){switch(r){case n.isProxy:return!0;case n.source:return e;case"with":return function(...t){return u(e,...t)};case"body":if(!t.body)return i("",e);if(t.body[n.isProxy])return t.body;return i(t.body,e);case"ok":return e.status>=200&&e.status<400;case"headers":return e.headers;default:if(r in t&&"toString"!=r)return t[r];if(r in e&&"toString"!=r){if("function"==typeof e[r])return function(...t){return e[r].apply(e,t)};return e[r]}}}})}function l(e,t){"function"==typeof t?t(e.searchParams,e):(t=new URLSearchParams(t)).forEach((t,r)=>{e.searchParams.append(r,t)})}function p(...e){let t=["hash","host","hostname","href","password","pathname","port","protocol","username","search","searchParams"],r=new URL("https://localhost/");for(let n of e)if("string"==typeof n||n instanceof String)r=new URL(n,r);else if(n instanceof URL||"undefined"!=typeof Location&&n instanceof Location)r=new URL(n);else if(n instanceof URLSearchParams)l(r,n);else if(n&&"object"==typeof n)for(let s in n)if("search"==s)"function"==typeof n.search?n.search(r.search,r):r.search=new URLSearchParams(n.search);else if("searchParams"==s)l(r,n.searchParams);else{if(!t.includes(s))throw w("metro.url: unknown url parameter "+o+"url/unknown-param-name/",s);if("function"==typeof n[s])n[s](r[s],r);else if("string"==typeof n[s]||n[s]instanceof String||"number"==typeof n[s]||n[s]instanceof Number||"boolean"==typeof n[s]||n[s]instanceof Boolean)r[s]=""+n[s];else if("object"==typeof n[s]&&n[s].toString)r[s]=n[s].toString();else throw w("metro.url: unsupported value for "+s+" "+o+"url/unsupported-param-value/",e[s])}else throw w("metro.url: unsupported option value "+o+"url/unsupported-option-value/",n);return Object.freeze(r),new Proxy(r,{get(e,t,r){switch(t){case n.isProxy:return!0;case n.source:return e;case"with":return function(...t){return p(e,...t)};case"toString":case"toJSON":return function(){return e[t]()}}return e[t]}})}let d=(e,...t)=>{console.error("Ⓜ️ ",e,...t)},y=(e,...t)=>{console.info("Ⓜ️ ",e,...t)},h=e=>{console.group("Ⓜ️ "+e)},b=e=>{console.groupEnd("Ⓜ️ "+e)};function w(e,...t){return d(e,...t),Error(e,...t)}let m={add(e,t){s.tracers[e]=t},delete(e){delete s.tracers[e]},clear(){s.tracers={}},group(){let e=0;return{request:(t,r)=>{h(++e),y(t?.url,t,r)},response:(t,r)=>{y(t?.body?t.body[n.source]:null,t,r),b(e),e--}}}}});var s=(n("hkeot"),n("hkeot"));n("hkeot"),window.metro=Object.assign({},s,{mw:{jsonmw:function(e){return e=Object.assign({reviver:null,replacer:null,space:""},e),async(t,r)=>{["POST","PUT","PATCH","QUERY"].includes(t.method)?(t=t.with({headers:{"Content-Type":"application/json",Accept:"application/json"}})).body&&"object"==typeof t.body[s.symbols.source]&&(t=t.with({body:JSON.stringify(t.body[s.symbols.source],e.replacer,e.space)})):t=t.with({headers:{Accept:"application/json"}});let o=await r(t),n=JSON.parse(await o.text(),e.reviver);return o.with({body:n})}},thrower:function(e){return async(t,r)=>{let o=await r(t);if(!o.ok){if(e&&"function"==typeof e[o.status])o=e[o.status].apply(o,t);else throw Error(o.status+": "+o.statusText,{cause:o})}return o}}}}); //# sourceMappingURL=everything.js.map diff --git a/dist/everything.js.map b/dist/everything.js.map index 637b48b..f729b73 100644 --- a/dist/everything.js.map +++ b/dist/everything.js.map @@ -1 +1 @@ -{"mappings":"A,S,E,C,C,C,C,C,C,C,E,O,c,C,E,E,C,I,E,I,E,W,C,E,a,C,C,E,C,I,E,W,E,C,E,E,C,E,E,E,iB,A,O,I,A,C,E,S,C,E,G,K,E,O,C,C,E,C,O,C,G,K,E,C,I,E,C,C,E,A,Q,C,C,E,C,I,E,C,G,E,Q,C,C,E,O,C,C,E,C,E,E,I,C,E,O,C,E,E,O,E,E,O,A,C,I,E,A,M,uB,E,I,O,E,I,C,mB,C,C,E,Q,C,S,C,C,C,E,C,C,E,C,C,E,E,iB,C,G,A,C,E,E,Q,A,E,Q,S,C,C,C,E,E,E,O,C,U,I,G,E,E,O,C,U,I,G,E,E,O,C,a,I,G,E,E,O,C,W,I,G,E,E,O,C,S,I,G,E,E,O,C,M,I,G,E,E,O,C,W,ICipBO,SAAS,EAAS,GAAG,CAAO,EAElC,IAAI,EAAS,IAAI,SACjB,IAAK,IAAI,KAAU,EAClB,GAAI,aAAkB,SACrB,IAAK,IAAI,KAAS,EAAO,OAAO,GAC/B,EAAO,MAAM,CAAC,CAAK,CAAC,EAAE,CAAC,CAAK,CAAC,EAAE,OAE1B,GAAI,GAAU,AAAiB,UAAjB,OAAO,EAC3B,IAAK,IAAI,KAAS,OAAO,OAAO,CAAC,GAChC,GAAI,MAAM,OAAO,CAAC,CAAK,CAAC,EAAE,EACzB,IAAK,IAAI,KAAS,CAAK,CAAC,EAAE,CACzB,EAAO,MAAM,CAAC,CAAK,CAAC,EAAE,CAAE,QAGzB,EAAO,MAAM,CAAC,CAAK,CAAC,EAAE,CAAC,CAAK,CAAC,EAAE,OAIjC,MAAM,IAAI,EAAW,yEAAyE,GAIhG,OADA,OAAO,MAAM,CAAC,GACP,IAAI,MAAM,EAAQ,CACxB,IAAK,CAAC,EAAO,EAAK,KACjB,OAAO,GACN,KAAK,EAAQ,OAAO,CACnB,MAAO,CAAA,CAER,MAAK,EAAQ,MAAM,CAClB,OAAO,CAER,KAAK,OACJ,OAAO,SAAS,GAAG,CAAO,EACzB,OAAO,EAAS,KAAW,EAC5B,CAED,KAAK,WACL,IAAK,SACJ,OAAO,WACN,OAAO,CAAM,CAAC,EAAK,EACpB,CAEF,CACA,OAAO,CAAM,CAAC,EAAK,AACpB,CACD,EACD,G,E,E,O,C,Q,I,GA7rBA,IAAM,EAAW,iCAOJ,EAAU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","sources":["","src/metro.mjs","src/everything.mjs","src/mw/json.mjs","src/mw/thrower.mjs"],"sourcesContent":["\nfunction $parcel$export(e, n, v, s) {\n Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});\n}\n\n var $parcel$global = globalThis;\n \nvar $parcel$modules = {};\nvar $parcel$inits = {};\n\nvar parcelRequire = $parcel$global[\"parcelRequireea2c\"];\n\nif (parcelRequire == null) {\n parcelRequire = function(id) {\n if (id in $parcel$modules) {\n return $parcel$modules[id].exports;\n }\n if (id in $parcel$inits) {\n var init = $parcel$inits[id];\n delete $parcel$inits[id];\n var module = {id: id, exports: {}};\n $parcel$modules[id] = module;\n init.call(module.exports, module, module.exports);\n return module.exports;\n }\n var err = new Error(\"Cannot find module '\" + id + \"'\");\n err.code = 'MODULE_NOT_FOUND';\n throw err;\n };\n\n parcelRequire.register = function register(id, init) {\n $parcel$inits[id] = init;\n };\n\n $parcel$global[\"parcelRequireea2c\"] = parcelRequire;\n}\n\nvar parcelRegister = parcelRequire.register;\nparcelRegister(\"hkeot\", function(module, exports) {\n\n$parcel$export(module.exports, \"symbols\", () => $86c8ab3a59b0bae1$export$47616e9f7f5fe113);\n$parcel$export(module.exports, \"request\", () => $86c8ab3a59b0bae1$export$b5fe3f66a567bec0);\n$parcel$export(module.exports, \"metroError\", () => $86c8ab3a59b0bae1$export$7079e2c78c274c66);\n$parcel$export(module.exports, \"response\", () => $86c8ab3a59b0bae1$export$785bb8ef7fad1f74);\n$parcel$export(module.exports, \"client\", () => $86c8ab3a59b0bae1$export$388e0302ca0d9a41);\n$parcel$export(module.exports, \"url\", () => $86c8ab3a59b0bae1$export$128fa18b7194ef);\n$parcel$export(module.exports, \"formdata\", () => $86c8ab3a59b0bae1$export$5de500aade6bf050);\n$parcel$export(module.exports, \"trace\", () => $86c8ab3a59b0bae1$export$357889f174732d38);\n/**\n * base URL used to link to more information about an error message\n */ const $86c8ab3a59b0bae1$var$metroURL = \"https://metro.muze.nl/details/\";\nconst $86c8ab3a59b0bae1$export$47616e9f7f5fe113 = {\n isProxy: Symbol(\"isProxy\"),\n source: Symbol(\"source\")\n};\n/**\n * Metro HTTP Client with middleware support\n * @method get\n * @method post\n * @method put\n * @method delete\n * @method patch\n * @method head\n * @method options\n * @method query\n */ class $86c8ab3a59b0bae1$var$Client {\n #options = {\n url: typeof window != \"undefined\" ? window.location : \"https://localhost\"\n };\n #verbs = [\n \"get\",\n \"post\",\n \"put\",\n \"delete\",\n \"patch\",\n \"head\",\n \"options\",\n \"query\"\n ];\n static tracers = {};\n /**\n\t * @typedef {Object} ClientOptions\n\t * @property {Array} middlewares - list of middleware functions\n\t * @property {string|URL} url - default url of the client\n\t * @property {[string]} verbs - a list of verb methods to expose, e.g. ['get','post']\n\t * \n\t * Constructs a new metro client. Can have any number of params.\n\t * @params {ClientOptions|URL|Function|Client}\n\t * @returns {Client} - A metro client object with given or default verb methods\n\t */ constructor(...options){\n for (let option of options){\n if (typeof option == \"string\" || option instanceof String) this.#options.url = \"\" + option;\n else if (option instanceof $86c8ab3a59b0bae1$var$Client) Object.assign(this.#options, option.#options);\n else if (option instanceof Function) this.#addMiddlewares([\n option\n ]);\n else if (option && typeof option == \"object\") for(let param in option){\n if (param == \"middlewares\") this.#addMiddlewares(option[param]);\n else if (typeof option[param] == \"function\") this.#options[param] = option[param](this.#options[param], this.#options);\n else this.#options[param] = option[param];\n }\n }\n if (this.#options.verbs) {\n this.#verbs = this.#options.verbs;\n delete this.#options.verbs;\n }\n for (const verb of this.#verbs)this[verb] = async function(...options) {\n return this.fetch($86c8ab3a59b0bae1$export$b5fe3f66a567bec0(this.#options, ...options, {\n method: verb.toUpperCase()\n }));\n };\n Object.freeze(this);\n }\n #addMiddlewares(middlewares) {\n if (typeof middlewares == \"function\") middlewares = [\n middlewares\n ];\n let index = middlewares.findIndex((m)=>typeof m != \"function\");\n if (index >= 0) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"metro.client: middlewares must be a function or an array of functions \" + $86c8ab3a59b0bae1$var$metroURL + \"client/invalid-middlewares-value/\", middlewares[index]);\n if (!Array.isArray(this.#options.middlewares)) this.#options.middlewares = [];\n this.#options.middlewares = this.#options.middlewares.concat(middlewares);\n }\n /**\n\t * Mimics the standard browser fetch method, but uses any middleware installed through\n\t * the constructor.\n\t * @param {Request|string|Object} - Required. The URL or Request object, accepts all types that are accepted by metro.request\n\t * @param {Object} - Optional. Any object that is accepted by metro.request\n\t * @return {Promise} - The metro.response to this request, or any other result as changed by any included middleware.\n\t */ fetch(req, options) {\n req = $86c8ab3a59b0bae1$export$b5fe3f66a567bec0(req, options);\n if (!req.url) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"metro.client.\" + req.method.toLowerCase() + \": Missing url parameter \" + $86c8ab3a59b0bae1$var$metroURL + \"client/missing-url-param/\", req);\n if (!options) options = {};\n if (!(typeof options === \"object\") || Array.isArray(options) || options instanceof String) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"metro.client.fetch: Options is not an object\");\n const metrofetch = async function browserFetch(req) {\n if (req[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy]) // even though a Proxy is supposed to be 'invisible'\n // fetch() doesn't work with the proxy (in Firefox), \n // you need the actual Request object here\n req = req[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.source];\n const res = await fetch(req);\n return $86c8ab3a59b0bae1$export$785bb8ef7fad1f74(res);\n };\n let middlewares = [\n metrofetch\n ].concat(this.#options?.middlewares?.slice() || []);\n options = Object.assign({}, this.#options, options);\n //@TODO: do this once in constructor?\n let next;\n for (let middleware of middlewares)next = function(next, middleware) {\n return async function(req) {\n let res;\n let tracers = Object.values($86c8ab3a59b0bae1$var$Client.tracers);\n for (let tracer of tracers)if (tracer.request) tracer.request.call(tracer, req, middleware);\n res = await middleware(req, next);\n for (let tracer of tracers)if (tracer.response) tracer.response.call(tracer, res, middleware);\n return res;\n };\n }(next, middleware);\n return next(req);\n }\n with(...options) {\n return new $86c8ab3a59b0bae1$var$Client(this, ...options);\n }\n}\nfunction $86c8ab3a59b0bae1$export$388e0302ca0d9a41(...options) {\n return new $86c8ab3a59b0bae1$var$Client(...options);\n}\nfunction $86c8ab3a59b0bae1$var$appendHeaders(r, headers) {\n if (!Array.isArray(headers)) headers = [\n headers\n ];\n headers.forEach((header)=>{\n if (typeof header == \"function\") {\n let result = header(r.headers, r);\n if (result) {\n if (!Array.isArray(result)) result = [\n result\n ];\n headers = headers.concat(result);\n }\n }\n });\n headers.forEach((header)=>{\n Object.entries(header).forEach(([name, value])=>{\n r.headers.append(name, value);\n });\n });\n}\nfunction $86c8ab3a59b0bae1$var$bodyProxy(body, r) {\n let source = r.body;\n if (!source) {\n //Firefox does not allow access to Request.body (undefined)\n //Chrome and Nodejs do, so mimic the correct (documented)\n //result here\n if (body === null) source = new ReadableStream();\n else if (body instanceof ReadableStream) source = body;\n else if (body instanceof Blob) source = body.stream();\n else source = new ReadableStream({\n start (controller) {\n let chunk;\n switch(typeof body){\n case \"object\":\n if (typeof body.toString == \"function\") // also catches URLSearchParams\n chunk = body.toString();\n else if (body instanceof FormData) chunk = new URLSearchParams(body).toString();\n else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) // catchs TypedArrays - e.g. Uint16Array\n chunk = body;\n else throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"Cannot convert body to ReadableStream\", body);\n break;\n case \"string\":\n case \"number\":\n case \"boolean\":\n chunk = body;\n break;\n default:\n throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"Cannot convert body to ReadableStream\", body);\n }\n controller.enqueue(chunk);\n controller.close();\n }\n });\n }\n return new Proxy(source, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return body;\n case \"toString\":\n return function() {\n return \"\" + body;\n };\n }\n if (typeof body == \"object\") {\n if (prop in body) {\n if (typeof body[prop] == \"function\") return function(...args) {\n return body[prop].apply(body, args);\n };\n return body[prop];\n }\n }\n if (prop in target && prop != \"toString\") {\n // skipped toString, since it has no usable output\n // and body may have its own toString\n if (typeof target[prop] == \"function\") return function(...args) {\n return target[prop].apply(target, args);\n };\n return target[prop];\n }\n },\n has (target, prop) {\n return prop in body;\n },\n ownKeys (target) {\n return Reflect.ownKeys(body);\n },\n getOwnPropertyDescriptor (target, prop) {\n return Object.getOwnPropertyDescriptor(body, prop);\n }\n });\n}\nfunction $86c8ab3a59b0bae1$var$getRequestParams(req, current) {\n let params = current || {};\n if (!params.url && current.url) params.url = current.url;\n // function to fetch all relevant properties of a Request\n for (let prop of [\n \"method\",\n \"headers\",\n \"body\",\n \"mode\",\n \"credentials\",\n \"cache\",\n \"redirect\",\n \"referrer\",\n \"referrerPolicy\",\n \"integrity\",\n \"keepalive\",\n \"signal\",\n \"priority\",\n \"url\"\n ]){\n if (typeof req[prop] == \"function\") req[prop](params[prop], params);\n else if (typeof req[prop] != \"undefined\") {\n if (prop == \"url\") params.url = $86c8ab3a59b0bae1$export$128fa18b7194ef(params.url, req.url);\n else if (prop == \"headers\") {\n params.headers = new Headers(current.headers);\n if (!(req.headers instanceof Headers)) req.headers = new Headers(req.headers);\n for (let [key, value] of req.headers.entries())params.headers.set(key, value);\n } else params[prop] = req[prop];\n }\n }\n return params;\n}\nfunction $86c8ab3a59b0bae1$export$b5fe3f66a567bec0(...options) {\n // the standard Request constructor is a minefield\n // so first gather all the options together into a single\n // javascript object, then set it in one go\n let requestParams = {\n url: typeof window != \"undefined\" ? window.location : \"https://localhost/\",\n duplex: \"half\" // required when setting body to ReadableStream, just set it here by default already\n };\n for (let option of options){\n if (typeof option == \"string\" || option instanceof URL || option instanceof URLSearchParams) requestParams.url = $86c8ab3a59b0bae1$export$128fa18b7194ef(requestParams.url, option);\n else if (option && (option instanceof FormData || option instanceof ReadableStream || option instanceof Blob || option instanceof ArrayBuffer || option instanceof DataView)) requestParams.body = option;\n else if (option && typeof option == \"object\") Object.assign(requestParams, $86c8ab3a59b0bae1$var$getRequestParams(option, requestParams));\n }\n let body = requestParams.body;\n if (body) {\n if (typeof body == \"object\" && !(body instanceof String) && !(body instanceof ReadableStream) && !(body instanceof Blob) && !(body instanceof ArrayBuffer) && !(body instanceof DataView) && !(body instanceof FormData) && !(body instanceof URLSearchParams) && (typeof TypedArray == \"undefined\" || !(body instanceof TypedArray))) requestParams.body = JSON.stringify(body);\n }\n let r = new Request(requestParams.url, requestParams);\n Object.freeze(r);\n return new Proxy(r, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case \"with\":\n return function(...options) {\n if (body) options.unshift({\n body: body\n }) // unshifted so it can be overridden by options\n ;\n return $86c8ab3a59b0bae1$export$b5fe3f66a567bec0(target, ...options);\n };\n case \"toString\":\n case \"toJSON\":\n return function() {\n return target[prop].apply(target);\n };\n case \"blob\":\n case \"text\":\n case \"json\":\n return function() {\n return target[prop].apply(target);\n };\n case \"body\":\n // Request.body is always a ReadableStream\n // which is a horrible API, if you want to\n // allow middleware to alter the body\n // so we keep the original body, wrap a Proxy\n // around it to keep the ReadableStream api\n // accessible, but allow access to the original\n // body value as well\n if (!body) body = target.body;\n if (body) {\n if (body[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy]) return body;\n return $86c8ab3a59b0bae1$var$bodyProxy(body, target);\n }\n break;\n }\n return target[prop];\n }\n });\n}\nfunction $86c8ab3a59b0bae1$var$getResponseParams(res, current) {\n // function to fetch all relevant properties of a Response\n let params = current || {};\n if (!params.url && current.url) params.url = current.url;\n for (let prop of [\n \"status\",\n \"statusText\",\n \"headers\",\n \"body\",\n \"url\",\n \"type\",\n \"redirected\"\n ]){\n if (typeof res[prop] == \"function\") res[prop](params[prop], params);\n else if (typeof res[prop] != \"undefined\") {\n if (prop == \"url\") params.url = new URL(res.url, params.url || \"https://localhost/\");\n else params[prop] = res[prop];\n }\n }\n return params;\n}\nfunction $86c8ab3a59b0bae1$export$785bb8ef7fad1f74(...options) {\n let responseParams = {};\n for (let option of options){\n if (typeof option == \"string\") responseParams.body = option;\n else if (option instanceof Response) Object.assign(responseParams, $86c8ab3a59b0bae1$var$getResponseParams(option, responseParams));\n else if (option && typeof option == \"object\") {\n if (option instanceof FormData || option instanceof Blob || option instanceof ArrayBuffer || option instanceof DataView || option instanceof ReadableStream || option instanceof URLSearchParams || option instanceof String || typeof TypedArray != \"undefined\" && option instanceof TypedArray) responseParams.body = option;\n else Object.assign(responseParams, $86c8ab3a59b0bae1$var$getResponseParams(option, responseParams));\n }\n }\n let r = new Response(responseParams.body, responseParams);\n Object.freeze(r);\n return new Proxy(r, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case \"with\":\n return function(...options) {\n return $86c8ab3a59b0bae1$export$785bb8ef7fad1f74(target, ...options);\n };\n case \"body\":\n if (responseParams.body) {\n if (responseParams.body[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy]) return responseParams.body;\n return $86c8ab3a59b0bae1$var$bodyProxy(responseParams.body, target);\n } else return $86c8ab3a59b0bae1$var$bodyProxy(\"\", target);\n break;\n case \"ok\":\n return target.status >= 200 && target.status < 400;\n case \"headers\":\n return target.headers;\n default:\n if (prop in responseParams && prop != \"toString\") return responseParams[prop];\n if (prop in target && prop != \"toString\") {\n // skipped toString, since it has no usable output\n // and body may have its own toString\n if (typeof target[prop] == \"function\") return function(...args) {\n return target[prop].apply(target, args);\n };\n return target[prop];\n }\n break;\n }\n return undefined;\n }\n });\n}\nfunction $86c8ab3a59b0bae1$var$appendSearchParams(url, params) {\n if (typeof params == \"function\") params(url.searchParams, url);\n else {\n params = new URLSearchParams(params);\n params.forEach((value, key)=>{\n url.searchParams.append(key, value);\n });\n }\n}\nfunction $86c8ab3a59b0bae1$export$128fa18b7194ef(...options) {\n let validParams = [\n \"hash\",\n \"host\",\n \"hostname\",\n \"href\",\n \"password\",\n \"pathname\",\n \"port\",\n \"protocol\",\n \"username\",\n \"search\",\n \"searchParams\"\n ];\n let u = new URL(\"https://localhost/\");\n for (let option of options){\n if (typeof option == \"string\" || option instanceof String) // option is a relative or absolute url\n u = new URL(option, u);\n else if (option instanceof URL || typeof Location != \"undefined\" && option instanceof Location) u = new URL(option);\n else if (option instanceof URLSearchParams) $86c8ab3a59b0bae1$var$appendSearchParams(u, option);\n else if (option && typeof option == \"object\") for(let param in option){\n if (param == \"search\") {\n if (typeof option.search == \"function\") option.search(u.search, u);\n else u.search = new URLSearchParams(option.search);\n } else if (param == \"searchParams\") $86c8ab3a59b0bae1$var$appendSearchParams(u, option.searchParams);\n else {\n if (!validParams.includes(param)) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"metro.url: unknown url parameter \" + $86c8ab3a59b0bae1$var$metroURL + \"url/unknown-param-name/\", param);\n if (typeof option[param] == \"function\") option[param](u[param], u);\n else if (typeof option[param] == \"string\" || option[param] instanceof String || typeof option[param] == \"number\" || option[param] instanceof Number || typeof option[param] == \"boolean\" || option[param] instanceof Boolean) u[param] = \"\" + option[param];\n else if (typeof option[param] == \"object\" && option[param].toString) u[param] = option[param].toString();\n else throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"metro.url: unsupported value for \" + param + \" \" + $86c8ab3a59b0bae1$var$metroURL + \"url/unsupported-param-value/\", options[param]);\n }\n }\n else throw $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"metro.url: unsupported option value \" + $86c8ab3a59b0bae1$var$metroURL + \"url/unsupported-option-value/\", option);\n }\n Object.freeze(u);\n return new Proxy(u, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case \"with\":\n return function(...options) {\n return $86c8ab3a59b0bae1$export$128fa18b7194ef(target, ...options);\n };\n case \"toString\":\n case \"toJSON\":\n return function() {\n return target[prop]();\n };\n }\n return target[prop];\n }\n });\n}\nfunction $86c8ab3a59b0bae1$export$5de500aade6bf050(...options) {\n var params = new FormData();\n for (let option of options){\n if (option instanceof FormData) for (let entry of option.entries())params.append(entry[0], entry[1]);\n else if (option && typeof option == \"object\") for (let entry of Object.entries(option)){\n if (Array.isArray(entry[1])) for (let value of entry[1])params.append(entry[0], value);\n else params.append(entry[0], entry[1]);\n }\n else throw new $86c8ab3a59b0bae1$export$7079e2c78c274c66(\"metro.formdata: unknown option type, only FormData or Object supported\", option);\n }\n Object.freeze(params);\n return new Proxy(params, {\n get: (target, prop, receiver)=>{\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case \"with\":\n return function(...options) {\n return $86c8ab3a59b0bae1$export$5de500aade6bf050(target, ...options);\n };\n case \"toString\":\n case \"toJSON\":\n return function() {\n return target[prop]();\n };\n }\n return target[prop];\n }\n });\n}\nconst $86c8ab3a59b0bae1$var$metroConsole = {\n error: (message, ...details)=>{\n console.error(\"\\u24C2\\uFE0F \", message, ...details);\n },\n info: (message, ...details)=>{\n console.info(\"\\u24C2\\uFE0F \", message, ...details);\n },\n group: (name)=>{\n console.group(\"\\u24C2\\uFE0F \" + name);\n },\n groupEnd: (name)=>{\n console.groupEnd(\"\\u24C2\\uFE0F \" + name);\n }\n};\nfunction $86c8ab3a59b0bae1$export$7079e2c78c274c66(message, ...details) {\n $86c8ab3a59b0bae1$var$metroConsole.error(message, ...details);\n return new Error(message, ...details);\n}\nconst $86c8ab3a59b0bae1$export$357889f174732d38 = {\n /**\n\t * Adds a named tracer function\n\t * @param {string} name - the name of the tracer\n\t * @param {Function} tracer - the tracer function to call\n\t */ add (name, tracer) {\n $86c8ab3a59b0bae1$var$Client.tracers[name] = tracer;\n },\n /**\n\t * Removes a named tracer function\n\t * @param {string} name\n\t */ delete (name) {\n delete $86c8ab3a59b0bae1$var$Client.tracers[name];\n },\n /**\n\t * Removes all tracer functions\n\t */ clear () {\n $86c8ab3a59b0bae1$var$Client.tracers = {};\n },\n /**\n\t * Returns a set of request and response tracer functions that use the\n\t * console.group feature to shows nested request/response pairs, with\n\t * most commonly needed information for debugging\n\t */ group () {\n let group = 0;\n return {\n request: (req, middleware)=>{\n group++;\n $86c8ab3a59b0bae1$var$metroConsole.group(group);\n $86c8ab3a59b0bae1$var$metroConsole.info(req?.url, req, middleware);\n },\n response: (res, middleware)=>{\n $86c8ab3a59b0bae1$var$metroConsole.info(res?.body ? res.body[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.source] : null, res, middleware);\n $86c8ab3a59b0bae1$var$metroConsole.groupEnd(group);\n group--;\n }\n };\n }\n};\n\n});\n\n\nvar $hkeot = parcelRequire(\"hkeot\");\n\nvar $hkeot = parcelRequire(\"hkeot\");\nfunction $9cea4e31d030ec91$export$2e2bcd8739ae039(options) {\n options = Object.assign({\n reviver: null,\n replacer: null,\n space: \"\"\n }, options);\n return async (req, next)=>{\n if ([\n \"POST\",\n \"PUT\",\n \"PATCH\",\n \"QUERY\"\n ].includes(req.method)) {\n req = req.with({\n headers: {\n \"Content-Type\": \"application/json\",\n \"Accept\": \"application/json\"\n }\n });\n if (req.body && typeof req.body[$hkeot.symbols.source] == \"object\") req = req.with({\n body: JSON.stringify(req.body[$hkeot.symbols.source], options.replacer, options.space)\n });\n } else req = req.with({\n headers: {\n \"Accept\": \"application/json\"\n }\n });\n let res = await next(req);\n let body = await res.text();\n let json = JSON.parse(body, options.reviver);\n return res.with({\n body: json\n });\n };\n}\n\n\nparcelRequire(\"hkeot\");\nfunction $55b2c766a737f106$export$2e2bcd8739ae039(options) {\n return async (req, next)=>{\n let res = await next(req);\n if (!res.ok) {\n if (options && typeof options[res.status] == \"function\") res = options[res.status].apply(res, req);\n else throw new Error(res.status + \": \" + res.statusText, {\n cause: res\n });\n }\n return res;\n };\n}\n\n\nwindow.metro = Object.assign({}, $hkeot, {\n mw: {\n jsonmw: $9cea4e31d030ec91$export$2e2bcd8739ae039,\n thrower: $55b2c766a737f106$export$2e2bcd8739ae039\n }\n});\n\n\n//# sourceMappingURL=everything.js.map\n","/**\n * base URL used to link to more information about an error message\n */\nconst metroURL = 'https://metro.muze.nl/details/'\n\n/**\n * Symbols:\n * - isProxy: used to test if an object is a metro Proxy to another object\n * - source: used to return the actual source (target) of a metro Proxy\n */\nexport const symbols = {\n\tisProxy: Symbol('isProxy'),\n\tsource: Symbol('source')\n}\n\n/**\n * Metro HTTP Client with middleware support\n * @method get\n * @method post\n * @method put\n * @method delete\n * @method patch\n * @method head\n * @method options\n * @method query\n */\nclass Client\n{\n\t#options = {\n\t\turl: typeof window != 'undefined' ? window.location : 'https://localhost'\n\t}\n\t#verbs = ['get','post','put','delete','patch','head','options','query']\n\n\tstatic tracers = {}\n\n\t/**\n\t * @typedef {Object} ClientOptions\n\t * @property {Array} middlewares - list of middleware functions\n\t * @property {string|URL} url - default url of the client\n\t * @property {[string]} verbs - a list of verb methods to expose, e.g. ['get','post']\n\t * \n\t * Constructs a new metro client. Can have any number of params.\n\t * @params {ClientOptions|URL|Function|Client}\n\t * @returns {Client} - A metro client object with given or default verb methods\n\t */\n\tconstructor(...options)\n\t{\n\t\tfor (let option of options) {\n\t\t\tif (typeof option == 'string' || option instanceof String) {\n\t\t\t\tthis.#options.url = ''+option\n\t\t\t} else if (option instanceof Client) {\n\t\t\t\tObject.assign(this.#options, option.#options)\n\t\t\t} else if (option instanceof Function) {\n\t\t\t\tthis.#addMiddlewares([option])\n\t\t\t} else if (option && typeof option == 'object') {\n\t\t\t\tfor (let param in option) {\n\t\t\t\t\tif (param == 'middlewares') {\n\t\t\t\t\t\tthis.#addMiddlewares(option[param])\n\t\t\t\t\t} else if (typeof option[param] == 'function') {\n\t\t\t\t\t\tthis.#options[param] = option[param](this.#options[param], this.#options)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.#options[param] = option[param]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.#options.verbs) {\n\t\t\tthis.#verbs = this.#options.verbs\n\t\t\tdelete this.#options.verbs\n\t\t}\n\n\t\tfor (const verb of this.#verbs) {\n\t\t\tthis[verb] = async function(...options) {\n\t\t\t\treturn this.fetch(request(\n\t\t\t\t\tthis.#options,\n\t\t\t\t\t...options,\n\t\t\t\t\t{method: verb.toUpperCase()}\n\t\t\t\t))\n\t\t\t}\n\t\t}\n\t\tObject.freeze(this)\n\t}\n\n\t#addMiddlewares(middlewares)\n\t{\n\t\tif (typeof middlewares == 'function') {\n\t\t\tmiddlewares = [ middlewares ]\n\t\t}\n\t\tlet index = middlewares.findIndex(m => typeof m != 'function')\n\t\tif (index>=0) {\n\t\t\tthrow metroError('metro.client: middlewares must be a function or an array of functions '\n\t\t\t\t+metroURL+'client/invalid-middlewares-value/', middlewares[index])\n\t\t}\n\t\tif (!Array.isArray(this.#options.middlewares)) {\n\t\t\tthis.#options.middlewares = []\n\t\t}\n\t\tthis.#options.middlewares = this.#options.middlewares.concat(middlewares)\n\t}\n\n\t/**\n\t * Mimics the standard browser fetch method, but uses any middleware installed through\n\t * the constructor.\n\t * @param {Request|string|Object} - Required. The URL or Request object, accepts all types that are accepted by metro.request\n\t * @param {Object} - Optional. Any object that is accepted by metro.request\n\t * @return {Promise} - The metro.response to this request, or any other result as changed by any included middleware.\n\t */\n\tfetch(req, options)\n\t{\n\t\treq = request(req, options)\n\t\tif (!req.url) {\n\t\t\tthrow metroError('metro.client.'+req.method.toLowerCase()+': Missing url parameter '+metroURL+'client/missing-url-param/', req)\n\t\t}\n\t\tif (!options) {\n\t\t\toptions = {}\n\t\t}\n\t\tif (!(typeof options === 'object') \n\t\t\t|| Array.isArray(options)\n\t\t\t|| options instanceof String) \n\t\t{\n\t\t\tthrow metroError('metro.client.fetch: Options is not an object')\n\t\t}\n\n\t\tconst metrofetch = async function browserFetch(req)\n\t\t{\n\t\t\tif (req[symbols.isProxy]) {\n\t\t\t\t// even though a Proxy is supposed to be 'invisible'\n\t\t\t\t// fetch() doesn't work with the proxy (in Firefox), \n\t\t\t\t// you need the actual Request object here\n\t\t\t\treq = req[symbols.source]\n\t\t\t}\n\t\t\tconst res = await fetch(req)\n\t\t\treturn response(res)\n\t\t}\n\t\t\n\t\tlet middlewares = [metrofetch].concat(this.#options?.middlewares?.slice() || [])\n\t\toptions = Object.assign({}, this.#options, options)\n\t\t//@TODO: do this once in constructor?\n\t\tlet next\n\t\tfor (let middleware of middlewares) {\n\t\t\tnext = (function(next, middleware) {\n\t\t\t\treturn async function(req) {\n\t\t\t\t\tlet res\n\t\t\t\t\tlet tracers = Object.values(Client.tracers)\n\t\t\t\t\tfor(let tracer of tracers) {\n\t\t\t\t\t\tif (tracer.request) {\n\t\t\t\t\t\t\ttracer.request.call(tracer, req, middleware)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tres = await middleware(req, next)\n\t\t\t\t\tfor(let tracer of tracers) {\n\t\t\t\t\t\tif (tracer.response) {\n\t\t\t\t\t\t\ttracer.response.call(tracer, res, middleware)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn res\n\t\t\t\t}\t\t\t\t\t\t\t\t\n\t\t\t})(next, middleware)\n\t\t}\n\t\treturn next(req)\n\t}\n\n\twith(...options) {\n\t\treturn new Client(this, ...options)\n\t}\n}\n\n/**\n * Returns a new metro Client object.\n * @param {...ClientOptions|string|URL}\n * @return Client\n */\nexport function client(...options)\n{\n\treturn new Client(...options)\n}\n\nfunction appendHeaders(r, headers)\n{\n\tif (!Array.isArray(headers)) {\n\t\theaders = [headers]\n\t}\n\theaders.forEach((header) => {\n\t\tif (typeof header == 'function') {\n\t\t\tlet result = header(r.headers, r)\n\t\t\tif (result) {\n\t\t\t\tif (!Array.isArray(result)) {\n\t\t\t\t\tresult = [result]\n\t\t\t\t}\n\t\t\t\theaders = headers.concat(result)\n\t\t\t}\n\t\t}\n\t})\n\theaders.forEach((header) => {\n\t\tObject.entries(header).forEach(([name,value]) => {\t\t\t\n\t\t\tr.headers.append(name, value)\n\t\t})\n\t})\n}\n\nfunction bodyProxy(body, r)\n{\n\tlet source = r.body\n\tif (!source) {\n\t\t//Firefox does not allow access to Request.body (undefined)\n\t\t//Chrome and Nodejs do, so mimic the correct (documented)\n\t\t//result here\n\t\tif (body === null) {\n\t\t\tsource = new ReadableStream()\n\t\t} else if (body instanceof ReadableStream) {\n\t\t\tsource = body\n\t\t} else if (body instanceof Blob) {\n\t\t\tsource = body.stream()\n\t\t} else {\n\t\t\tsource = new ReadableStream({\n\t\t\t\tstart(controller) {\n\t\t\t\t\tlet chunk\n\t\t\t\t\tswitch(typeof body) {\n\t\t\t\t\t\tcase 'object':\n\t\t\t\t\t\t\tif (typeof body.toString == 'function') {\n\t\t\t\t\t\t\t\t// also catches URLSearchParams\n\t\t\t\t\t\t\t\tchunk = body.toString()\n\t\t\t\t\t\t\t} else if (body instanceof FormData) {\n\t\t\t\t\t\t\t\tchunk = new URLSearchParams(body).toString()\n\t\t\t\t\t\t\t} else if (body instanceof ArrayBuffer\n\t\t\t\t\t\t\t\t|| ArrayBuffer.isView(body)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t// catchs TypedArrays - e.g. Uint16Array\n\t\t\t\t\t\t\t\tchunk = body\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthrow metroError('Cannot convert body to ReadableStream', body)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'string':\n\t\t\t\t\t\tcase 'number':\n\t\t\t\t\t\tcase 'boolean':\n\t\t\t\t\t\t\tchunk = body\n\t\t\t\t\t\tbreak\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow metroError('Cannot convert body to ReadableStream', body)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcontroller.enqueue(chunk)\n\t\t\t\t\tcontroller.close()\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\treturn new Proxy(source, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch (prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn body\n\t\t\t\tbreak\n\t\t\t\tcase 'toString':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn ''+body\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (typeof body == 'object') {\n\t\t\t\tif (prop in body) {\n\t\t\t\t\tif (typeof body[prop] == 'function') {\n\t\t\t\t\t\treturn function(...args) {\n\t\t\t\t\t\t\treturn body[prop].apply(body, args)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn body[prop]\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (prop in target && prop != 'toString') {\n\t\t\t\t// skipped toString, since it has no usable output\n\t\t\t\t// and body may have its own toString\n\t\t\t\tif (typeof target[prop] == 'function') {\n\t\t\t\t\treturn function(...args) {\n\t\t\t\t\t\treturn target[prop].apply(target, args)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn target[prop]\n\t\t\t}\n\t\t},\n\t\thas(target, prop) {\n\t\t\treturn prop in body\n\t\t},\n\t\townKeys(target) {\n\t\t\treturn Reflect.ownKeys(body)\n\t\t},\n\t\tgetOwnPropertyDescriptor(target, prop) {\n\t\t\treturn Object.getOwnPropertyDescriptor(body,prop)\n\t\t}\n\t})\n}\n\nfunction getRequestParams(req, current)\n{\n\tlet params = current || {}\n\tif (!params.url && current.url) {\n\t\tparams.url = current.url\n\t}\n\t// function to fetch all relevant properties of a Request\n\tfor(let prop of ['method','headers','body','mode','credentials','cache','redirect',\n\t\t'referrer','referrerPolicy','integrity','keepalive','signal',\n\t\t'priority','url']) {\n\t\tif (typeof req[prop] == 'function') {\n\t\t\treq[prop](params[prop], params)\n\t\t} else if (typeof req[prop] != 'undefined') {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = url(params.url, req.url)\n\t\t\t} else if (prop == 'headers') {\n\t\t\t\tparams.headers = new Headers(current.headers)\n\t\t\t\tif (!(req.headers instanceof Headers)) {\n\t\t\t\t\treq.headers = new Headers(req.headers)\n\t\t\t\t}\n\t\t\t\tfor (let [key, value] of req.headers.entries()) {\n\t\t\t\t\tparams.headers.set(key, value)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparams[prop] = req[prop]\n\t\t\t}\n\t\t}\n\t}\n\treturn params\n}\n\n/**\n * @typedef {Request} MetroRequest\n * @property {Symbol(source)} - returns the target Request of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroRequest, with the given options added\n * @param {} ...options - request options, handled in order\n * \n * Returns a new metro Request object\n * @param {} ...options - request options, handled in order\n * @return {MetroRequest} - a new metro Request object\n */\nexport function request(...options)\n{\n\t// the standard Request constructor is a minefield\n\t// so first gather all the options together into a single\n\t// javascript object, then set it in one go\n\tlet requestParams = {\n\t\turl: typeof window != 'undefined' ? window.location : 'https://localhost/',\n\t\tduplex: 'half' // required when setting body to ReadableStream, just set it here by default already\n\t}\n\tfor (let option of options) {\n\t\tif (typeof option == 'string'\n\t\t\t|| option instanceof URL\n\t\t\t|| option instanceof URLSearchParams\n\t\t) {\n\t\t\trequestParams.url = url(requestParams.url, option)\n\t\t} else if (option && (\n\t\t\toption instanceof FormData\n\t\t\t|| option instanceof ReadableStream\n\t\t\t|| option instanceof Blob\n\t\t\t|| option instanceof ArrayBuffer\n\t\t\t|| option instanceof DataView\n\t\t)) {\n\t\t\trequestParams.body = option\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tObject.assign(requestParams, getRequestParams(option, requestParams))\n\t\t}\n\t}\n\tlet body = requestParams.body\n\tif (body) {\n\t\tif (typeof body == 'object'\n\t\t\t&& !(body instanceof String)\n\t\t\t&& !(body instanceof ReadableStream)\n\t\t\t&& !(body instanceof Blob)\n\t\t\t&& !(body instanceof ArrayBuffer)\n\t\t\t&& !(body instanceof DataView)\n\t\t\t&& !(body instanceof FormData)\n\t\t\t&& !(body instanceof URLSearchParams)\n\t\t\t&& (typeof TypedArray=='undefined' || !(body instanceof TypedArray))\n\t\t) {\n\t\t\trequestParams.body = JSON.stringify(body)\n\t\t}\n\t}\n\tlet r = new Request(requestParams.url, requestParams)\n\tObject.freeze(r)\n\treturn new Proxy(r, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\tif (body) { // body is kept in a seperate value, if it set earlier\n\t\t\t\t\t\t\toptions.unshift({ body }) // unshifted so it can be overridden by options\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn request(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'toString':\n\t\t\t\tcase 'toJSON':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn target[prop].apply(target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'blob':\n\t\t\t\tcase 'text':\n\t\t\t\tcase 'json':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn target[prop].apply(target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'body':\n\t\t\t\t\t// Request.body is always a ReadableStream\n\t\t\t\t\t// which is a horrible API, if you want to\n\t\t\t\t\t// allow middleware to alter the body\n\t\t\t\t\t// so we keep the original body, wrap a Proxy\n\t\t\t\t\t// around it to keep the ReadableStream api\n\t\t\t\t\t// accessible, but allow access to the original\n\t\t\t\t\t// body value as well\n\t\t\t\t\tif (!body) {\n\t\t\t\t\t\tbody = target.body\n\t\t\t\t\t}\n\t\t\t\t\tif (body) {\n\t\t\t\t\t\tif (body[symbols.isProxy]) {\n\t\t\t\t\t\t\treturn body\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn bodyProxy(body, target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn target[prop]\n\t\t}\n\t})\n}\n\nfunction getResponseParams(res, current)\n{\n\t// function to fetch all relevant properties of a Response\n\tlet params = current || {}\n\tif (!params.url && current.url) {\n\t\tparams.url = current.url\n\t}\n\tfor(let prop of ['status','statusText','headers','body','url','type','redirected']) {\n\t\tif (typeof res[prop] == 'function') {\n\t\t\tres[prop](params[prop], params)\n\t\t} else if (typeof res[prop] != 'undefined') {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = new URL(res.url, params.url || 'https://localhost/')\n\t\t\t} else {\n\t\t\t\tparams[prop] = res[prop]\n\t\t\t}\n\t\t}\n\t}\n\treturn params\n}\n\n/**\n * @typedef {Response} MetroResponse\n * @property {Symbol(source)} - returns the target Response of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroResponse, with the given options added\n * @param {} ...options - respomse options, handled in order\n * \n * Returns a new metro Response object\n * @param {} ...options - request options, handled in order\n * @return {MetroResponse} - a new metro Response object\n */\nexport function response(...options)\n{\n\tlet responseParams = {}\n\tfor (let option of options) {\n\t\tif (typeof option == 'string') {\n\t\t\tresponseParams.body = option\n\t\t} else if (option instanceof Response) {\n\t\t\tObject.assign(responseParams, getResponseParams(option, responseParams))\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tif (option instanceof FormData\n\t\t\t\t|| option instanceof Blob\n\t\t\t\t|| option instanceof ArrayBuffer\n\t\t\t\t|| option instanceof DataView\n\t\t\t\t|| option instanceof ReadableStream\n\t\t\t\t|| option instanceof URLSearchParams\n\t\t\t\t|| option instanceof String\n\t\t\t\t|| (typeof TypedArray != 'undefined' && option instanceof TypedArray)\n\t\t\t) {\n\t\t\t\tresponseParams.body = option\n\t\t\t} else {\n\t\t\t\tObject.assign(responseParams, getResponseParams(option, responseParams))\n\t\t\t}\n\t\t}\n\t}\n\tlet r = new Response(responseParams.body, responseParams)\t\n\tObject.freeze(r)\n\treturn new Proxy(r, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\treturn response(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'body':\n\t\t\t\t\tif (responseParams.body) {\n\t\t\t\t\t\tif (responseParams.body[symbols.isProxy]) {\n\t\t\t\t\t\t\treturn responseParams.body\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn bodyProxy(responseParams.body, target)\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn bodyProxy('',target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'ok':\n\t\t\t\t\treturn (target.status>=200) && (target.status<400)\n\t\t\t\tbreak\n\t\t\t\tcase 'headers':\n\t\t\t\t\treturn target.headers\n\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\tif (prop in responseParams && prop != 'toString') {\n\t\t\t\t\t\treturn responseParams[prop]\n\t\t\t\t\t}\n\t\t\t\t\tif (prop in target && prop != 'toString') {\n\t\t\t\t\t\t// skipped toString, since it has no usable output\n\t\t\t\t\t\t// and body may have its own toString\n\t\t\t\t\t\tif (typeof target[prop] == 'function') {\n\t\t\t\t\t\t\treturn function(...args) {\n\t\t\t\t\t\t\t\treturn target[prop].apply(target, args)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn target[prop]\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn undefined\n\t\t}\n\t})\n}\n\nfunction appendSearchParams(url, params) {\n\tif (typeof params == 'function') {\n\t\t params(url.searchParams, url)\n\t} else {\n\t\tparams = new URLSearchParams(params)\n\t\tparams.forEach((value,key) => {\n\t\t\turl.searchParams.append(key, value)\n\t\t})\n\t}\n}\n\n/**\n * @typedef {URL} MetroURL\n * @property {Symbol(source)} - returns the target Request of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroRequest, with the given options added\n * @param {} ...options - url options, handled in order\n * \n * Returns a new metro URL object\n * @param {} ...options - url options, handled in order\n * @return {MetroURL} - a new metro URL object\n */\nexport function url(...options)\n{\n\tlet validParams = ['hash','host','hostname','href',\n\t\t\t'password','pathname','port','protocol','username','search','searchParams']\n\tlet u = new URL('https://localhost/')\n\tfor (let option of options) {\n\t\tif (typeof option == 'string' || option instanceof String) {\n\t\t\t// option is a relative or absolute url\n\t\t\tu = new URL(option, u)\n\t\t} else if (option instanceof URL \n\t\t\t|| (typeof Location != 'undefined' \n\t\t\t\t&& option instanceof Location)\n\t\t) {\n\t\t\tu = new URL(option)\n\t\t} else if (option instanceof URLSearchParams) {\n\t\t\tappendSearchParams(u, option)\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tfor (let param in option) {\n\t\t\t\tif (param=='search') {\n\t\t\t\t\tif (typeof option.search == 'function') {\n\t\t\t\t\t\toption.search(u.search, u)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tu.search = new URLSearchParams(option.search)\n\t\t\t\t\t}\n\t\t\t\t} else if (param=='searchParams') {\n\t\t\t\t\tappendSearchParams(u, option.searchParams)\n\t\t\t\t} else {\n\t\t\t\t\tif (!validParams.includes(param)) {\n\t\t\t\t\t\tthrow metroError('metro.url: unknown url parameter '+metroURL+'url/unknown-param-name/', param)\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof option[param] == 'function') {\n\t\t\t\t\t\toption[param](u[param], u)\n\t\t\t\t\t} else if (\n\t\t\t\t\t\ttypeof option[param] == 'string' || option[param] instanceof String \n\t\t\t\t\t\t|| typeof option[param] == 'number' || option[param] instanceof Number\n\t\t\t\t\t\t|| typeof option[param] == 'boolean' || option[param] instanceof Boolean\n\t\t\t\t\t) {\n\t\t\t\t\t\tu[param] = ''+option[param]\n\t\t\t\t\t} else if (typeof option[param] == 'object' && option[param].toString) {\n\t\t\t\t\t\tu[param] = option[param].toString()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow metroError('metro.url: unsupported value for '+param+' '+metroURL+'url/unsupported-param-value/', options[param])\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow metroError('metro.url: unsupported option value '+metroURL+'url/unsupported-option-value/', option)\n\t\t}\n\t}\n\tObject.freeze(u)\n\treturn new Proxy(u, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\treturn url(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'toString':\n\t\t\t\tcase 'toJSON':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn target[prop]()\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn target[prop]\n\t\t}\n\t})\n}\n\n/**\n * @typedef {FormData} MetroFormData\n * @property {Symbol(source)} - returns the target Request of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroRequest, with the given options added\n * @param {} ...options - url options, handled in order\n * \n * Returns a new metro FormData object\n * @param {} ...options - formdata options, handled in order\n * @return {MetroURL} - a new metro FormData object\n */\nexport function formdata(...options)\n{\n\tvar params = new FormData()\n\tfor (let option of options) {\n\t\tif (option instanceof FormData) {\n\t\t\tfor (let entry of option.entries()) {\n\t\t\t\tparams.append(entry[0],entry[1])\n\t\t\t}\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tfor (let entry of Object.entries(option)) {\n\t\t\t\tif (Array.isArray(entry[1])) {\n\t\t\t\t\tfor (let value of entry[1]) {\n\t\t\t\t\t\tparams.append(entry[0], value)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tparams.append(entry[0],entry[1])\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new metroError('metro.formdata: unknown option type, only FormData or Object supported',option)\n\t\t}\n\t}\n\tObject.freeze(params)\n\treturn new Proxy(params, {\n\t\tget: (target,prop,receiver) => {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\treturn formdata(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'toString':\n\t\t\t\tcase 'toJSON':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn target[prop]()\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn target[prop]\n\t\t}\n\t})\n}\n\nconst metroConsole = {\n\terror: (message, ...details) => {\n\t\tconsole.error('Ⓜ️ ',message, ...details)\n\t},\n\tinfo: (message, ...details) => {\n\t\tconsole.info('Ⓜ️ ',message, ...details)\n\t},\n\tgroup: (name) => {\n\t\tconsole.group('Ⓜ️ '+name)\n\t},\n\tgroupEnd: (name) => {\n\t\tconsole.groupEnd('Ⓜ️ '+name)\n\t}\n}\n\n\n/**\n * Custom Metro Error function that outputs to the console then throws an error\n */\nexport function metroError(message, ...details) {\n\tmetroConsole.error(message, ...details)\n\treturn new Error(message, ...details)\n}\n\n/**\n * Set of debugging tools to trace the request - response flow\n * Tracer are run on all metro fetch calls\n */\nexport const trace = {\n\t/**\n\t * Adds a named tracer function\n\t * @param {string} name - the name of the tracer\n\t * @param {Function} tracer - the tracer function to call\n\t */\n\tadd(name, tracer) {\n\t\tClient.tracers[name] = tracer\n\t},\n\t/**\n\t * Removes a named tracer function\n\t * @param {string} name\n\t */\n\tdelete(name) {\n\t\tdelete Client.tracers[name]\n\t},\n\t/**\n\t * Removes all tracer functions\n\t */\n\tclear() {\n\t\tClient.tracers = {}\n\t},\n\t/**\n\t * Returns a set of request and response tracer functions that use the\n\t * console.group feature to shows nested request/response pairs, with\n\t * most commonly needed information for debugging\n\t */\n\tgroup() {\n\t\tlet group = 0;\n\t\treturn {\n\t\t\trequest: (req, middleware) => {\n\t\t\t\tgroup++\n\t\t\t\tmetroConsole.group(group)\n\t\t\t\tmetroConsole.info(req?.url, req, middleware)\n\t\t\t},\n\t\t\tresponse: (res, middleware) => {\n\t\t\t\tmetroConsole.info(res?.body ? res.body[symbols.source]: null, res, middleware)\n\t\t\t\tmetroConsole.groupEnd(group)\n\t\t\t\tgroup--\n\t\t\t}\n\t\t}\n\t}\n}\n","import * as metro from './metro.mjs'\nimport jsonmw from './mw/json.mjs'\nimport thrower from './mw/thrower.mjs'\n\nwindow.metro = Object.assign({}, metro, {\n\tmw: {\n\t\tjsonmw,\n\t\tthrower\n\t}\n})","import * as metro from '../metro.mjs'\n\nexport default function jsonmw(options) {\n\toptions = Object.assign({\n\t\treviver: null,\n\t\treplacer: null,\n\t\tspace: ''\n\t}, options)\n\n\treturn async (req, next) => {\n\t\tif (['POST','PUT','PATCH','QUERY'].includes(req.method)) {\n\t\t\treq = req.with({\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type':'application/json',\n\t 'Accept':'application/json'\n\t\t\t\t}\n\t\t\t})\n\t\t\tif (req.body && typeof req.body[metro.symbols.source] == 'object') {\n\t\t\t\treq = req.with({\n\t\t\t\t\tbody: JSON.stringify(req.body[metro.symbols.source], options.replacer, options.space)\n\t\t\t\t})\n\t\t\t}\n\t\t} else {\n\t\t\treq = req.with({\n\t\t\t\theaders: {\n\t\t\t 'Accept':'application/json'\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\tlet res = await next(req)\n\t\tlet body = await res.text()\n\t\tlet json = JSON.parse(body, options.reviver)\n\t\treturn res.with({\n\t\t\tbody: json\n\t\t})\n\t}\n}","import * as metro from '../metro.mjs'\n\nexport default function thrower(options) {\n\n\treturn async (req, next) => {\n\t\tlet res = await next(req)\n\t\tif (!res.ok) {\n\t\t\tif (options && typeof options[res.status] == 'function') {\n\t\t\t\tres = options[res.status].apply(res, req)\n\t\t\t} else {\n\t\t\t\tthrow new Error(res.status+': '+res.statusText, {\n\t\t\t\t\tcause: res\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\treturn res\n\t}\n\n}"],"names":["$parcel$export","e","n","v","s","Object","defineProperty","get","set","enumerable","configurable","$parcel$global","globalThis","$parcel$modules","$parcel$inits","parcelRequire","id","exports","init","module","call","err","Error","code","register","parcelRegister","$86c8ab3a59b0bae1$export$47616e9f7f5fe113","$86c8ab3a59b0bae1$export$b5fe3f66a567bec0","$86c8ab3a59b0bae1$export$7079e2c78c274c66","$86c8ab3a59b0bae1$export$785bb8ef7fad1f74","$86c8ab3a59b0bae1$export$388e0302ca0d9a41","$86c8ab3a59b0bae1$export$128fa18b7194ef","$86c8ab3a59b0bae1$export$5de500aade6bf050","options","params","FormData","option","entry","entries","append","Array","isArray","value","freeze","Proxy","target","prop","receiver","isProxy","source","$86c8ab3a59b0bae1$export$357889f174732d38","$86c8ab3a59b0bae1$var$metroURL","Symbol","$86c8ab3a59b0bae1$var$Client","url","window","location","verbs","tracers","constructor","String","assign","Function","addMiddlewares","param","verb","fetch","method","toUpperCase","middlewares","index","findIndex","m","concat","req","next","toLowerCase","slice","middleware","res","values","tracer","request","response","with","$86c8ab3a59b0bae1$var$bodyProxy","body","r","ReadableStream","Blob","stream","start","controller","chunk","toString","URLSearchParams","ArrayBuffer","isView","enqueue","close","args","apply","has","ownKeys","Reflect","getOwnPropertyDescriptor","requestParams","duplex","URL","DataView","$86c8ab3a59b0bae1$var$getRequestParams","current","key","headers","Headers","TypedArray","JSON","stringify","Request","unshift","$86c8ab3a59b0bae1$var$getResponseParams","responseParams","Response","status","$86c8ab3a59b0bae1$var$appendSearchParams","searchParams","forEach","validParams","u","Location","search","includes","Number","Boolean","message","details","console","error","info","name","group","groupEnd","$86c8ab3a59b0bae1$var$metroConsole","add","delete","clear","$hkeot","metro","mw","jsonmw","reviver","replacer","space","symbols","json","parse","text","thrower","ok","statusText","cause"],"version":3,"file":"everything.js.map","sourceRoot":"../"} \ No newline at end of file +{"mappings":"A,S,E,C,C,C,C,C,C,C,E,O,c,C,E,E,C,I,E,I,E,W,C,E,a,C,C,E,C,I,E,W,E,C,E,E,C,E,E,E,iB,A,O,I,A,C,E,S,C,E,G,K,E,O,C,C,E,C,O,C,G,K,E,C,I,E,C,C,E,A,Q,C,C,E,C,I,E,C,G,E,Q,C,C,E,O,C,C,E,C,E,E,I,C,E,O,C,E,E,O,E,E,O,A,C,I,E,A,M,uB,E,I,O,E,I,C,mB,C,C,E,Q,C,S,C,C,C,E,C,C,E,C,C,E,E,iB,C,G,A,C,E,E,Q,A,E,Q,S,C,C,C,E,E,E,O,C,U,I,G,E,E,O,C,U,I,G,E,E,O,C,a,I,G,E,E,O,C,W,I,G,E,E,O,C,S,I,G,E,E,O,C,M,I,G,E,E,O,C,W,ICipBO,SAAS,EAAS,GAAG,CAAO,EAElC,IAAI,EAAS,IAAI,SACjB,IAAK,IAAI,KAAU,EAClB,GAAI,aAAkB,SACrB,IAAK,IAAI,KAAS,EAAO,OAAO,GAC/B,EAAO,MAAM,CAAC,CAAK,CAAC,EAAE,CAAC,CAAK,CAAC,EAAE,OAE1B,GAAI,GAAU,AAAiB,UAAjB,OAAO,EAC3B,IAAK,IAAI,KAAS,OAAO,OAAO,CAAC,GAChC,GAAI,MAAM,OAAO,CAAC,CAAK,CAAC,EAAE,EACzB,IAAK,IAAI,KAAS,CAAK,CAAC,EAAE,CACzB,EAAO,MAAM,CAAC,CAAK,CAAC,EAAE,CAAE,QAGzB,EAAO,MAAM,CAAC,CAAK,CAAC,EAAE,CAAC,CAAK,CAAC,EAAE,OAIjC,MAAM,IAAI,EAAW,yEAAyE,GAIhG,OADA,OAAO,MAAM,CAAC,GACP,IAAI,MAAM,EAAQ,CACxB,IAAK,CAAC,EAAO,EAAK,KACjB,OAAO,GACN,KAAK,EAAQ,OAAO,CACnB,MAAO,CAAA,CAER,MAAK,EAAQ,MAAM,CAClB,OAAO,CAER,KAAK,OACJ,OAAO,SAAS,GAAG,CAAO,EACzB,OAAO,EAAS,KAAW,EAC5B,CAQF,CACA,OAAO,CAAM,CAAC,EAAK,AACpB,CACD,EACD,G,E,E,O,C,Q,I,GA7rBA,IAAM,EAAW,iCAOJ,EAAU,CACtB,QAAS,OAAO,WAChB,OAAQ,OAAO,SAChB,CAaA,OAAM,EAEL,CAAA,CA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","sources":["","src/metro.mjs","src/everything.mjs","src/mw/json.mjs","src/mw/thrower.mjs"],"sourcesContent":["\nfunction $parcel$export(e, n, v, s) {\n Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});\n}\n\n var $parcel$global = globalThis;\n \nvar $parcel$modules = {};\nvar $parcel$inits = {};\n\nvar parcelRequire = $parcel$global[\"parcelRequire94c2\"];\n\nif (parcelRequire == null) {\n parcelRequire = function(id) {\n if (id in $parcel$modules) {\n return $parcel$modules[id].exports;\n }\n if (id in $parcel$inits) {\n var init = $parcel$inits[id];\n delete $parcel$inits[id];\n var module = {id: id, exports: {}};\n $parcel$modules[id] = module;\n init.call(module.exports, module, module.exports);\n return module.exports;\n }\n var err = new Error(\"Cannot find module '\" + id + \"'\");\n err.code = 'MODULE_NOT_FOUND';\n throw err;\n };\n\n parcelRequire.register = function register(id, init) {\n $parcel$inits[id] = init;\n };\n\n $parcel$global[\"parcelRequire94c2\"] = parcelRequire;\n}\n\nvar parcelRegister = parcelRequire.register;\nparcelRegister(\"hkeot\", function(module, exports) {\n\n$parcel$export(module.exports, \"symbols\", () => $86c8ab3a59b0bae1$export$47616e9f7f5fe113);\n$parcel$export(module.exports, \"request\", () => $86c8ab3a59b0bae1$export$b5fe3f66a567bec0);\n$parcel$export(module.exports, \"metroError\", () => $86c8ab3a59b0bae1$export$7079e2c78c274c66);\n$parcel$export(module.exports, \"response\", () => $86c8ab3a59b0bae1$export$785bb8ef7fad1f74);\n$parcel$export(module.exports, \"client\", () => $86c8ab3a59b0bae1$export$388e0302ca0d9a41);\n$parcel$export(module.exports, \"url\", () => $86c8ab3a59b0bae1$export$128fa18b7194ef);\n$parcel$export(module.exports, \"formdata\", () => $86c8ab3a59b0bae1$export$5de500aade6bf050);\n$parcel$export(module.exports, \"trace\", () => $86c8ab3a59b0bae1$export$357889f174732d38);\n/**\n * base URL used to link to more information about an error message\n */ const $86c8ab3a59b0bae1$var$metroURL = 'https://metro.muze.nl/details/';\nconst $86c8ab3a59b0bae1$export$47616e9f7f5fe113 = {\n isProxy: Symbol('isProxy'),\n source: Symbol('source')\n};\n/**\n * Metro HTTP Client with middleware support\n * @method get\n * @method post\n * @method put\n * @method delete\n * @method patch\n * @method head\n * @method options\n * @method query\n */ class $86c8ab3a59b0bae1$var$Client {\n #options = {\n url: typeof window != 'undefined' ? window.location : 'https://localhost'\n };\n #verbs = [\n 'get',\n 'post',\n 'put',\n 'delete',\n 'patch',\n 'head',\n 'options',\n 'query'\n ];\n static tracers = {};\n /**\n\t * @typedef {Object} ClientOptions\n\t * @property {Array} middlewares - list of middleware functions\n\t * @property {string|URL} url - default url of the client\n\t * @property {[string]} verbs - a list of verb methods to expose, e.g. ['get','post']\n\t * \n\t * Constructs a new metro client. Can have any number of params.\n\t * @params {ClientOptions|URL|Function|Client}\n\t * @returns {Client} - A metro client object with given or default verb methods\n\t */ constructor(...options){\n for (let option of options){\n if (typeof option == 'string' || option instanceof String) this.#options.url = '' + option;\n else if (option instanceof $86c8ab3a59b0bae1$var$Client) Object.assign(this.#options, option.#options);\n else if (option instanceof Function) this.#addMiddlewares([\n option\n ]);\n else if (option && typeof option == 'object') for(let param in option){\n if (param == 'middlewares') this.#addMiddlewares(option[param]);\n else if (typeof option[param] == 'function') this.#options[param] = option[param](this.#options[param], this.#options);\n else this.#options[param] = option[param];\n }\n }\n if (this.#options.verbs) {\n this.#verbs = this.#options.verbs;\n delete this.#options.verbs;\n }\n for (const verb of this.#verbs)this[verb] = async function(...options) {\n return this.fetch($86c8ab3a59b0bae1$export$b5fe3f66a567bec0(this.#options, ...options, {\n method: verb.toUpperCase()\n }));\n };\n Object.freeze(this);\n }\n #addMiddlewares(middlewares) {\n if (typeof middlewares == 'function') middlewares = [\n middlewares\n ];\n let index = middlewares.findIndex((m)=>typeof m != 'function');\n if (index >= 0) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('metro.client: middlewares must be a function or an array of functions ' + $86c8ab3a59b0bae1$var$metroURL + 'client/invalid-middlewares-value/', middlewares[index]);\n if (!Array.isArray(this.#options.middlewares)) this.#options.middlewares = [];\n this.#options.middlewares = this.#options.middlewares.concat(middlewares);\n }\n /**\n\t * Mimics the standard browser fetch method, but uses any middleware installed through\n\t * the constructor.\n\t * @param {Request|string|Object} - Required. The URL or Request object, accepts all types that are accepted by metro.request\n\t * @param {Object} - Optional. Any object that is accepted by metro.request\n\t * @return {Promise} - The metro.response to this request, or any other result as changed by any included middleware.\n\t */ fetch(req, options) {\n req = $86c8ab3a59b0bae1$export$b5fe3f66a567bec0(req, options);\n if (!req.url) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('metro.client.' + req.method.toLowerCase() + ': Missing url parameter ' + $86c8ab3a59b0bae1$var$metroURL + 'client/missing-url-param/', req);\n if (!options) options = {};\n if (!(typeof options === 'object') || Array.isArray(options) || options instanceof String) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('metro.client.fetch: Options is not an object');\n const metrofetch = async function browserFetch(req) {\n if (req[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy]) // even though a Proxy is supposed to be 'invisible'\n // fetch() doesn't work with the proxy (in Firefox), \n // you need the actual Request object here\n req = req[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.source];\n const res = await fetch(req);\n return $86c8ab3a59b0bae1$export$785bb8ef7fad1f74(res);\n };\n let middlewares = [\n metrofetch\n ].concat(this.#options?.middlewares?.slice() || []);\n options = Object.assign({}, this.#options, options);\n //@TODO: do this once in constructor?\n let next;\n for (let middleware of middlewares)next = function(next, middleware) {\n return async function(req) {\n let res;\n let tracers = Object.values($86c8ab3a59b0bae1$var$Client.tracers);\n for (let tracer of tracers)if (tracer.request) tracer.request.call(tracer, req, middleware);\n res = await middleware(req, next);\n for (let tracer of tracers)if (tracer.response) tracer.response.call(tracer, res, middleware);\n return res;\n };\n }(next, middleware);\n return next(req);\n }\n with(...options) {\n return new $86c8ab3a59b0bae1$var$Client(this, ...options);\n }\n}\nfunction $86c8ab3a59b0bae1$export$388e0302ca0d9a41(...options) {\n return new $86c8ab3a59b0bae1$var$Client(...options);\n}\nfunction $86c8ab3a59b0bae1$var$appendHeaders(r, headers) {\n if (!Array.isArray(headers)) headers = [\n headers\n ];\n headers.forEach((header)=>{\n if (typeof header == 'function') {\n let result = header(r.headers, r);\n if (result) {\n if (!Array.isArray(result)) result = [\n result\n ];\n headers = headers.concat(result);\n }\n }\n });\n headers.forEach((header)=>{\n Object.entries(header).forEach(([name, value])=>{\n r.headers.append(name, value);\n });\n });\n}\nfunction $86c8ab3a59b0bae1$var$bodyProxy(body, r) {\n let source = r.body;\n if (!source) {\n //Firefox does not allow access to Request.body (undefined)\n //Chrome and Nodejs do, so mimic the correct (documented)\n //result here\n if (body === null) source = new ReadableStream();\n else if (body instanceof ReadableStream) source = body;\n else if (body instanceof Blob) source = body.stream();\n else source = new ReadableStream({\n start (controller) {\n let chunk;\n switch(typeof body){\n case 'object':\n if (typeof body.toString == 'function') // also catches URLSearchParams\n chunk = body.toString();\n else if (body instanceof FormData) chunk = new URLSearchParams(body).toString();\n else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) // catchs TypedArrays - e.g. Uint16Array\n chunk = body;\n else throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('Cannot convert body to ReadableStream', body);\n break;\n case 'string':\n case 'number':\n case 'boolean':\n chunk = body;\n break;\n default:\n throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('Cannot convert body to ReadableStream', body);\n }\n controller.enqueue(chunk);\n controller.close();\n }\n });\n }\n return new Proxy(source, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return body;\n case 'toString':\n return function() {\n return '' + body;\n };\n }\n if (typeof body == 'object') {\n if (prop in body) {\n if (typeof body[prop] == 'function') return function(...args) {\n return body[prop].apply(body, args);\n };\n return body[prop];\n }\n }\n if (prop in target && prop != 'toString') {\n // skipped toString, since it has no usable output\n // and body may have its own toString\n if (typeof target[prop] == 'function') return function(...args) {\n return target[prop].apply(target, args);\n };\n return target[prop];\n }\n },\n has (target, prop) {\n return prop in body;\n },\n ownKeys (target) {\n return Reflect.ownKeys(body);\n },\n getOwnPropertyDescriptor (target, prop) {\n return Object.getOwnPropertyDescriptor(body, prop);\n }\n });\n}\nfunction $86c8ab3a59b0bae1$var$getRequestParams(req, current) {\n let params = current || {};\n if (!params.url && current.url) params.url = current.url;\n // function to fetch all relevant properties of a Request\n for (let prop of [\n 'method',\n 'headers',\n 'body',\n 'mode',\n 'credentials',\n 'cache',\n 'redirect',\n 'referrer',\n 'referrerPolicy',\n 'integrity',\n 'keepalive',\n 'signal',\n 'priority',\n 'url'\n ]){\n if (typeof req[prop] == 'function') req[prop](params[prop], params);\n else if (typeof req[prop] != 'undefined') {\n if (prop == 'url') params.url = $86c8ab3a59b0bae1$export$128fa18b7194ef(params.url, req.url);\n else if (prop == 'headers') {\n params.headers = new Headers(current.headers);\n if (!(req.headers instanceof Headers)) req.headers = new Headers(req.headers);\n for (let [key, value] of req.headers.entries())params.headers.set(key, value);\n } else params[prop] = req[prop];\n }\n }\n return params;\n}\nfunction $86c8ab3a59b0bae1$export$b5fe3f66a567bec0(...options) {\n // the standard Request constructor is a minefield\n // so first gather all the options together into a single\n // javascript object, then set it in one go\n let requestParams = {\n url: typeof window != 'undefined' ? window.location : 'https://localhost/',\n duplex: 'half' // required when setting body to ReadableStream, just set it here by default already\n };\n for (let option of options){\n if (typeof option == 'string' || option instanceof URL || option instanceof URLSearchParams) requestParams.url = $86c8ab3a59b0bae1$export$128fa18b7194ef(requestParams.url, option);\n else if (option && (option instanceof FormData || option instanceof ReadableStream || option instanceof Blob || option instanceof ArrayBuffer || option instanceof DataView)) requestParams.body = option;\n else if (option && typeof option == 'object') Object.assign(requestParams, $86c8ab3a59b0bae1$var$getRequestParams(option, requestParams));\n }\n let body = requestParams.body;\n if (body) {\n if (typeof body == 'object' && !(body instanceof String) && !(body instanceof ReadableStream) && !(body instanceof Blob) && !(body instanceof ArrayBuffer) && !(body instanceof DataView) && !(body instanceof FormData) && !(body instanceof URLSearchParams) && (typeof TypedArray == 'undefined' || !(body instanceof TypedArray))) requestParams.body = JSON.stringify(body);\n }\n let r = new Request(requestParams.url, requestParams);\n Object.freeze(r);\n return new Proxy(r, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case 'with':\n return function(...options) {\n if (body) options.unshift({\n body: body\n }) // unshifted so it can be overridden by options\n ;\n return $86c8ab3a59b0bae1$export$b5fe3f66a567bec0(target, ...options);\n };\n case 'toString':\n case 'toJSON':\n return function() {\n return target[prop].apply(target);\n };\n case 'blob':\n case 'text':\n case 'json':\n return function() {\n return target[prop].apply(target);\n };\n case 'body':\n // Request.body is always a ReadableStream\n // which is a horrible API, if you want to\n // allow middleware to alter the body\n // so we keep the original body, wrap a Proxy\n // around it to keep the ReadableStream api\n // accessible, but allow access to the original\n // body value as well\n if (!body) body = target.body;\n if (body) {\n if (body[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy]) return body;\n return $86c8ab3a59b0bae1$var$bodyProxy(body, target);\n }\n break;\n }\n return target[prop];\n }\n });\n}\nfunction $86c8ab3a59b0bae1$var$getResponseParams(res, current) {\n // function to fetch all relevant properties of a Response\n let params = current || {};\n if (!params.url && current.url) params.url = current.url;\n for (let prop of [\n 'status',\n 'statusText',\n 'headers',\n 'body',\n 'url',\n 'type',\n 'redirected'\n ]){\n if (typeof res[prop] == 'function') res[prop](params[prop], params);\n else if (typeof res[prop] != 'undefined') {\n if (prop == 'url') params.url = new URL(res.url, params.url || 'https://localhost/');\n else params[prop] = res[prop];\n }\n }\n return params;\n}\nfunction $86c8ab3a59b0bae1$export$785bb8ef7fad1f74(...options) {\n let responseParams = {};\n for (let option of options){\n if (typeof option == 'string') responseParams.body = option;\n else if (option instanceof Response) Object.assign(responseParams, $86c8ab3a59b0bae1$var$getResponseParams(option, responseParams));\n else if (option && typeof option == 'object') {\n if (option instanceof FormData || option instanceof Blob || option instanceof ArrayBuffer || option instanceof DataView || option instanceof ReadableStream || option instanceof URLSearchParams || option instanceof String || typeof TypedArray != 'undefined' && option instanceof TypedArray) responseParams.body = option;\n else Object.assign(responseParams, $86c8ab3a59b0bae1$var$getResponseParams(option, responseParams));\n }\n }\n let r = new Response(responseParams.body, responseParams);\n Object.freeze(r);\n return new Proxy(r, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case 'with':\n return function(...options) {\n return $86c8ab3a59b0bae1$export$785bb8ef7fad1f74(target, ...options);\n };\n case 'body':\n if (responseParams.body) {\n if (responseParams.body[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy]) return responseParams.body;\n return $86c8ab3a59b0bae1$var$bodyProxy(responseParams.body, target);\n } else return $86c8ab3a59b0bae1$var$bodyProxy('', target);\n break;\n case 'ok':\n return target.status >= 200 && target.status < 400;\n case 'headers':\n return target.headers;\n default:\n if (prop in responseParams && prop != 'toString') return responseParams[prop];\n if (prop in target && prop != 'toString') {\n // skipped toString, since it has no usable output\n // and body may have its own toString\n if (typeof target[prop] == 'function') return function(...args) {\n return target[prop].apply(target, args);\n };\n return target[prop];\n }\n break;\n }\n return undefined;\n }\n });\n}\nfunction $86c8ab3a59b0bae1$var$appendSearchParams(url, params) {\n if (typeof params == 'function') params(url.searchParams, url);\n else {\n params = new URLSearchParams(params);\n params.forEach((value, key)=>{\n url.searchParams.append(key, value);\n });\n }\n}\nfunction $86c8ab3a59b0bae1$export$128fa18b7194ef(...options) {\n let validParams = [\n 'hash',\n 'host',\n 'hostname',\n 'href',\n 'password',\n 'pathname',\n 'port',\n 'protocol',\n 'username',\n 'search',\n 'searchParams'\n ];\n let u = new URL('https://localhost/');\n for (let option of options){\n if (typeof option == 'string' || option instanceof String) // option is a relative or absolute url\n u = new URL(option, u);\n else if (option instanceof URL || typeof Location != 'undefined' && option instanceof Location) u = new URL(option);\n else if (option instanceof URLSearchParams) $86c8ab3a59b0bae1$var$appendSearchParams(u, option);\n else if (option && typeof option == 'object') for(let param in option){\n if (param == 'search') {\n if (typeof option.search == 'function') option.search(u.search, u);\n else u.search = new URLSearchParams(option.search);\n } else if (param == 'searchParams') $86c8ab3a59b0bae1$var$appendSearchParams(u, option.searchParams);\n else {\n if (!validParams.includes(param)) throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('metro.url: unknown url parameter ' + $86c8ab3a59b0bae1$var$metroURL + 'url/unknown-param-name/', param);\n if (typeof option[param] == 'function') option[param](u[param], u);\n else if (typeof option[param] == 'string' || option[param] instanceof String || typeof option[param] == 'number' || option[param] instanceof Number || typeof option[param] == 'boolean' || option[param] instanceof Boolean) u[param] = '' + option[param];\n else if (typeof option[param] == 'object' && option[param].toString) u[param] = option[param].toString();\n else throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('metro.url: unsupported value for ' + param + ' ' + $86c8ab3a59b0bae1$var$metroURL + 'url/unsupported-param-value/', options[param]);\n }\n }\n else throw $86c8ab3a59b0bae1$export$7079e2c78c274c66('metro.url: unsupported option value ' + $86c8ab3a59b0bae1$var$metroURL + 'url/unsupported-option-value/', option);\n }\n Object.freeze(u);\n return new Proxy(u, {\n get (target, prop, receiver) {\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case 'with':\n return function(...options) {\n return $86c8ab3a59b0bae1$export$128fa18b7194ef(target, ...options);\n };\n case 'toString':\n case 'toJSON':\n return function() {\n return target[prop]();\n };\n }\n return target[prop];\n }\n });\n}\nfunction $86c8ab3a59b0bae1$export$5de500aade6bf050(...options) {\n var params = new FormData();\n for (let option of options){\n if (option instanceof FormData) for (let entry of option.entries())params.append(entry[0], entry[1]);\n else if (option && typeof option == 'object') for (let entry of Object.entries(option)){\n if (Array.isArray(entry[1])) for (let value of entry[1])params.append(entry[0], value);\n else params.append(entry[0], entry[1]);\n }\n else throw new $86c8ab3a59b0bae1$export$7079e2c78c274c66('metro.formdata: unknown option type, only FormData or Object supported', option);\n }\n Object.freeze(params);\n return new Proxy(params, {\n get: (target, prop, receiver)=>{\n switch(prop){\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.isProxy:\n return true;\n case $86c8ab3a59b0bae1$export$47616e9f7f5fe113.source:\n return target;\n case 'with':\n return function(...options) {\n return $86c8ab3a59b0bae1$export$5de500aade6bf050(target, ...options);\n };\n }\n return target[prop];\n }\n });\n}\nconst $86c8ab3a59b0bae1$var$metroConsole = {\n error: (message, ...details)=>{\n console.error(\"\\u24C2\\uFE0F \", message, ...details);\n },\n info: (message, ...details)=>{\n console.info(\"\\u24C2\\uFE0F \", message, ...details);\n },\n group: (name)=>{\n console.group(\"\\u24C2\\uFE0F \" + name);\n },\n groupEnd: (name)=>{\n console.groupEnd(\"\\u24C2\\uFE0F \" + name);\n }\n};\nfunction $86c8ab3a59b0bae1$export$7079e2c78c274c66(message, ...details) {\n $86c8ab3a59b0bae1$var$metroConsole.error(message, ...details);\n return new Error(message, ...details);\n}\nconst $86c8ab3a59b0bae1$export$357889f174732d38 = {\n /**\n\t * Adds a named tracer function\n\t * @param {string} name - the name of the tracer\n\t * @param {Function} tracer - the tracer function to call\n\t */ add (name, tracer) {\n $86c8ab3a59b0bae1$var$Client.tracers[name] = tracer;\n },\n /**\n\t * Removes a named tracer function\n\t * @param {string} name\n\t */ delete (name) {\n delete $86c8ab3a59b0bae1$var$Client.tracers[name];\n },\n /**\n\t * Removes all tracer functions\n\t */ clear () {\n $86c8ab3a59b0bae1$var$Client.tracers = {};\n },\n /**\n\t * Returns a set of request and response tracer functions that use the\n\t * console.group feature to shows nested request/response pairs, with\n\t * most commonly needed information for debugging\n\t */ group () {\n let group = 0;\n return {\n request: (req, middleware)=>{\n group++;\n $86c8ab3a59b0bae1$var$metroConsole.group(group);\n $86c8ab3a59b0bae1$var$metroConsole.info(req?.url, req, middleware);\n },\n response: (res, middleware)=>{\n $86c8ab3a59b0bae1$var$metroConsole.info(res?.body ? res.body[$86c8ab3a59b0bae1$export$47616e9f7f5fe113.source] : null, res, middleware);\n $86c8ab3a59b0bae1$var$metroConsole.groupEnd(group);\n group--;\n }\n };\n }\n};\n\n});\n\n\nvar $hkeot = parcelRequire(\"hkeot\");\n\nvar $hkeot = parcelRequire(\"hkeot\");\nfunction $9cea4e31d030ec91$export$2e2bcd8739ae039(options) {\n options = Object.assign({\n reviver: null,\n replacer: null,\n space: ''\n }, options);\n return async (req, next)=>{\n if ([\n 'POST',\n 'PUT',\n 'PATCH',\n 'QUERY'\n ].includes(req.method)) {\n req = req.with({\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n }\n });\n if (req.body && typeof req.body[$hkeot.symbols.source] == 'object') req = req.with({\n body: JSON.stringify(req.body[$hkeot.symbols.source], options.replacer, options.space)\n });\n } else req = req.with({\n headers: {\n 'Accept': 'application/json'\n }\n });\n let res = await next(req);\n let body = await res.text();\n let json = JSON.parse(body, options.reviver);\n return res.with({\n body: json\n });\n };\n}\n\n\nparcelRequire(\"hkeot\");\nfunction $55b2c766a737f106$export$2e2bcd8739ae039(options) {\n return async (req, next)=>{\n let res = await next(req);\n if (!res.ok) {\n if (options && typeof options[res.status] == 'function') res = options[res.status].apply(res, req);\n else throw new Error(res.status + ': ' + res.statusText, {\n cause: res\n });\n }\n return res;\n };\n}\n\n\nwindow.metro = Object.assign({}, $hkeot, {\n mw: {\n jsonmw: $9cea4e31d030ec91$export$2e2bcd8739ae039,\n thrower: $55b2c766a737f106$export$2e2bcd8739ae039\n }\n});\n\n\n//# sourceMappingURL=everything.js.map\n","/**\n * base URL used to link to more information about an error message\n */\nconst metroURL = 'https://metro.muze.nl/details/'\n\n/**\n * Symbols:\n * - isProxy: used to test if an object is a metro Proxy to another object\n * - source: used to return the actual source (target) of a metro Proxy\n */\nexport const symbols = {\n\tisProxy: Symbol('isProxy'),\n\tsource: Symbol('source')\n}\n\n/**\n * Metro HTTP Client with middleware support\n * @method get\n * @method post\n * @method put\n * @method delete\n * @method patch\n * @method head\n * @method options\n * @method query\n */\nclass Client\n{\n\t#options = {\n\t\turl: typeof window != 'undefined' ? window.location : 'https://localhost'\n\t}\n\t#verbs = ['get','post','put','delete','patch','head','options','query']\n\n\tstatic tracers = {}\n\n\t/**\n\t * @typedef {Object} ClientOptions\n\t * @property {Array} middlewares - list of middleware functions\n\t * @property {string|URL} url - default url of the client\n\t * @property {[string]} verbs - a list of verb methods to expose, e.g. ['get','post']\n\t * \n\t * Constructs a new metro client. Can have any number of params.\n\t * @params {ClientOptions|URL|Function|Client}\n\t * @returns {Client} - A metro client object with given or default verb methods\n\t */\n\tconstructor(...options)\n\t{\n\t\tfor (let option of options) {\n\t\t\tif (typeof option == 'string' || option instanceof String) {\n\t\t\t\tthis.#options.url = ''+option\n\t\t\t} else if (option instanceof Client) {\n\t\t\t\tObject.assign(this.#options, option.#options)\n\t\t\t} else if (option instanceof Function) {\n\t\t\t\tthis.#addMiddlewares([option])\n\t\t\t} else if (option && typeof option == 'object') {\n\t\t\t\tfor (let param in option) {\n\t\t\t\t\tif (param == 'middlewares') {\n\t\t\t\t\t\tthis.#addMiddlewares(option[param])\n\t\t\t\t\t} else if (typeof option[param] == 'function') {\n\t\t\t\t\t\tthis.#options[param] = option[param](this.#options[param], this.#options)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.#options[param] = option[param]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.#options.verbs) {\n\t\t\tthis.#verbs = this.#options.verbs\n\t\t\tdelete this.#options.verbs\n\t\t}\n\n\t\tfor (const verb of this.#verbs) {\n\t\t\tthis[verb] = async function(...options) {\n\t\t\t\treturn this.fetch(request(\n\t\t\t\t\tthis.#options,\n\t\t\t\t\t...options,\n\t\t\t\t\t{method: verb.toUpperCase()}\n\t\t\t\t))\n\t\t\t}\n\t\t}\n\t\tObject.freeze(this)\n\t}\n\n\t#addMiddlewares(middlewares)\n\t{\n\t\tif (typeof middlewares == 'function') {\n\t\t\tmiddlewares = [ middlewares ]\n\t\t}\n\t\tlet index = middlewares.findIndex(m => typeof m != 'function')\n\t\tif (index>=0) {\n\t\t\tthrow metroError('metro.client: middlewares must be a function or an array of functions '\n\t\t\t\t+metroURL+'client/invalid-middlewares-value/', middlewares[index])\n\t\t}\n\t\tif (!Array.isArray(this.#options.middlewares)) {\n\t\t\tthis.#options.middlewares = []\n\t\t}\n\t\tthis.#options.middlewares = this.#options.middlewares.concat(middlewares)\n\t}\n\n\t/**\n\t * Mimics the standard browser fetch method, but uses any middleware installed through\n\t * the constructor.\n\t * @param {Request|string|Object} - Required. The URL or Request object, accepts all types that are accepted by metro.request\n\t * @param {Object} - Optional. Any object that is accepted by metro.request\n\t * @return {Promise} - The metro.response to this request, or any other result as changed by any included middleware.\n\t */\n\tfetch(req, options)\n\t{\n\t\treq = request(req, options)\n\t\tif (!req.url) {\n\t\t\tthrow metroError('metro.client.'+req.method.toLowerCase()+': Missing url parameter '+metroURL+'client/missing-url-param/', req)\n\t\t}\n\t\tif (!options) {\n\t\t\toptions = {}\n\t\t}\n\t\tif (!(typeof options === 'object') \n\t\t\t|| Array.isArray(options)\n\t\t\t|| options instanceof String) \n\t\t{\n\t\t\tthrow metroError('metro.client.fetch: Options is not an object')\n\t\t}\n\n\t\tconst metrofetch = async function browserFetch(req)\n\t\t{\n\t\t\tif (req[symbols.isProxy]) {\n\t\t\t\t// even though a Proxy is supposed to be 'invisible'\n\t\t\t\t// fetch() doesn't work with the proxy (in Firefox), \n\t\t\t\t// you need the actual Request object here\n\t\t\t\treq = req[symbols.source]\n\t\t\t}\n\t\t\tconst res = await fetch(req)\n\t\t\treturn response(res)\n\t\t}\n\t\t\n\t\tlet middlewares = [metrofetch].concat(this.#options?.middlewares?.slice() || [])\n\t\toptions = Object.assign({}, this.#options, options)\n\t\t//@TODO: do this once in constructor?\n\t\tlet next\n\t\tfor (let middleware of middlewares) {\n\t\t\tnext = (function(next, middleware) {\n\t\t\t\treturn async function(req) {\n\t\t\t\t\tlet res\n\t\t\t\t\tlet tracers = Object.values(Client.tracers)\n\t\t\t\t\tfor(let tracer of tracers) {\n\t\t\t\t\t\tif (tracer.request) {\n\t\t\t\t\t\t\ttracer.request.call(tracer, req, middleware)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tres = await middleware(req, next)\n\t\t\t\t\tfor(let tracer of tracers) {\n\t\t\t\t\t\tif (tracer.response) {\n\t\t\t\t\t\t\ttracer.response.call(tracer, res, middleware)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn res\n\t\t\t\t}\t\t\t\t\t\t\t\t\n\t\t\t})(next, middleware)\n\t\t}\n\t\treturn next(req)\n\t}\n\n\twith(...options) {\n\t\treturn new Client(this, ...options)\n\t}\n}\n\n/**\n * Returns a new metro Client object.\n * @param {...ClientOptions|string|URL}\n * @return Client\n */\nexport function client(...options)\n{\n\treturn new Client(...options)\n}\n\nfunction appendHeaders(r, headers)\n{\n\tif (!Array.isArray(headers)) {\n\t\theaders = [headers]\n\t}\n\theaders.forEach((header) => {\n\t\tif (typeof header == 'function') {\n\t\t\tlet result = header(r.headers, r)\n\t\t\tif (result) {\n\t\t\t\tif (!Array.isArray(result)) {\n\t\t\t\t\tresult = [result]\n\t\t\t\t}\n\t\t\t\theaders = headers.concat(result)\n\t\t\t}\n\t\t}\n\t})\n\theaders.forEach((header) => {\n\t\tObject.entries(header).forEach(([name,value]) => {\t\t\t\n\t\t\tr.headers.append(name, value)\n\t\t})\n\t})\n}\n\nfunction bodyProxy(body, r)\n{\n\tlet source = r.body\n\tif (!source) {\n\t\t//Firefox does not allow access to Request.body (undefined)\n\t\t//Chrome and Nodejs do, so mimic the correct (documented)\n\t\t//result here\n\t\tif (body === null) {\n\t\t\tsource = new ReadableStream()\n\t\t} else if (body instanceof ReadableStream) {\n\t\t\tsource = body\n\t\t} else if (body instanceof Blob) {\n\t\t\tsource = body.stream()\n\t\t} else {\n\t\t\tsource = new ReadableStream({\n\t\t\t\tstart(controller) {\n\t\t\t\t\tlet chunk\n\t\t\t\t\tswitch(typeof body) {\n\t\t\t\t\t\tcase 'object':\n\t\t\t\t\t\t\tif (typeof body.toString == 'function') {\n\t\t\t\t\t\t\t\t// also catches URLSearchParams\n\t\t\t\t\t\t\t\tchunk = body.toString()\n\t\t\t\t\t\t\t} else if (body instanceof FormData) {\n\t\t\t\t\t\t\t\tchunk = new URLSearchParams(body).toString()\n\t\t\t\t\t\t\t} else if (body instanceof ArrayBuffer\n\t\t\t\t\t\t\t\t|| ArrayBuffer.isView(body)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t// catchs TypedArrays - e.g. Uint16Array\n\t\t\t\t\t\t\t\tchunk = body\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthrow metroError('Cannot convert body to ReadableStream', body)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'string':\n\t\t\t\t\t\tcase 'number':\n\t\t\t\t\t\tcase 'boolean':\n\t\t\t\t\t\t\tchunk = body\n\t\t\t\t\t\tbreak\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow metroError('Cannot convert body to ReadableStream', body)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcontroller.enqueue(chunk)\n\t\t\t\t\tcontroller.close()\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\treturn new Proxy(source, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch (prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn body\n\t\t\t\tbreak\n\t\t\t\tcase 'toString':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn ''+body\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (typeof body == 'object') {\n\t\t\t\tif (prop in body) {\n\t\t\t\t\tif (typeof body[prop] == 'function') {\n\t\t\t\t\t\treturn function(...args) {\n\t\t\t\t\t\t\treturn body[prop].apply(body, args)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn body[prop]\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (prop in target && prop != 'toString') {\n\t\t\t\t// skipped toString, since it has no usable output\n\t\t\t\t// and body may have its own toString\n\t\t\t\tif (typeof target[prop] == 'function') {\n\t\t\t\t\treturn function(...args) {\n\t\t\t\t\t\treturn target[prop].apply(target, args)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn target[prop]\n\t\t\t}\n\t\t},\n\t\thas(target, prop) {\n\t\t\treturn prop in body\n\t\t},\n\t\townKeys(target) {\n\t\t\treturn Reflect.ownKeys(body)\n\t\t},\n\t\tgetOwnPropertyDescriptor(target, prop) {\n\t\t\treturn Object.getOwnPropertyDescriptor(body,prop)\n\t\t}\n\t})\n}\n\nfunction getRequestParams(req, current)\n{\n\tlet params = current || {}\n\tif (!params.url && current.url) {\n\t\tparams.url = current.url\n\t}\n\t// function to fetch all relevant properties of a Request\n\tfor(let prop of ['method','headers','body','mode','credentials','cache','redirect',\n\t\t'referrer','referrerPolicy','integrity','keepalive','signal',\n\t\t'priority','url']) {\n\t\tif (typeof req[prop] == 'function') {\n\t\t\treq[prop](params[prop], params)\n\t\t} else if (typeof req[prop] != 'undefined') {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = url(params.url, req.url)\n\t\t\t} else if (prop == 'headers') {\n\t\t\t\tparams.headers = new Headers(current.headers)\n\t\t\t\tif (!(req.headers instanceof Headers)) {\n\t\t\t\t\treq.headers = new Headers(req.headers)\n\t\t\t\t}\n\t\t\t\tfor (let [key, value] of req.headers.entries()) {\n\t\t\t\t\tparams.headers.set(key, value)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparams[prop] = req[prop]\n\t\t\t}\n\t\t}\n\t}\n\treturn params\n}\n\n/**\n * @typedef {Request} MetroRequest\n * @property {Symbol(source)} - returns the target Request of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroRequest, with the given options added\n * @param {} ...options - request options, handled in order\n * \n * Returns a new metro Request object\n * @param {} ...options - request options, handled in order\n * @return {MetroRequest} - a new metro Request object\n */\nexport function request(...options)\n{\n\t// the standard Request constructor is a minefield\n\t// so first gather all the options together into a single\n\t// javascript object, then set it in one go\n\tlet requestParams = {\n\t\turl: typeof window != 'undefined' ? window.location : 'https://localhost/',\n\t\tduplex: 'half' // required when setting body to ReadableStream, just set it here by default already\n\t}\n\tfor (let option of options) {\n\t\tif (typeof option == 'string'\n\t\t\t|| option instanceof URL\n\t\t\t|| option instanceof URLSearchParams\n\t\t) {\n\t\t\trequestParams.url = url(requestParams.url, option)\n\t\t} else if (option && (\n\t\t\toption instanceof FormData\n\t\t\t|| option instanceof ReadableStream\n\t\t\t|| option instanceof Blob\n\t\t\t|| option instanceof ArrayBuffer\n\t\t\t|| option instanceof DataView\n\t\t)) {\n\t\t\trequestParams.body = option\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tObject.assign(requestParams, getRequestParams(option, requestParams))\n\t\t}\n\t}\n\tlet body = requestParams.body\n\tif (body) {\n\t\tif (typeof body == 'object'\n\t\t\t&& !(body instanceof String)\n\t\t\t&& !(body instanceof ReadableStream)\n\t\t\t&& !(body instanceof Blob)\n\t\t\t&& !(body instanceof ArrayBuffer)\n\t\t\t&& !(body instanceof DataView)\n\t\t\t&& !(body instanceof FormData)\n\t\t\t&& !(body instanceof URLSearchParams)\n\t\t\t&& (typeof TypedArray=='undefined' || !(body instanceof TypedArray))\n\t\t) {\n\t\t\trequestParams.body = JSON.stringify(body)\n\t\t}\n\t}\n\tlet r = new Request(requestParams.url, requestParams)\n\tObject.freeze(r)\n\treturn new Proxy(r, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\tif (body) { // body is kept in a seperate value, if it set earlier\n\t\t\t\t\t\t\toptions.unshift({ body }) // unshifted so it can be overridden by options\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn request(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'toString':\n\t\t\t\tcase 'toJSON':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn target[prop].apply(target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'blob':\n\t\t\t\tcase 'text':\n\t\t\t\tcase 'json':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn target[prop].apply(target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'body':\n\t\t\t\t\t// Request.body is always a ReadableStream\n\t\t\t\t\t// which is a horrible API, if you want to\n\t\t\t\t\t// allow middleware to alter the body\n\t\t\t\t\t// so we keep the original body, wrap a Proxy\n\t\t\t\t\t// around it to keep the ReadableStream api\n\t\t\t\t\t// accessible, but allow access to the original\n\t\t\t\t\t// body value as well\n\t\t\t\t\tif (!body) {\n\t\t\t\t\t\tbody = target.body\n\t\t\t\t\t}\n\t\t\t\t\tif (body) {\n\t\t\t\t\t\tif (body[symbols.isProxy]) {\n\t\t\t\t\t\t\treturn body\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn bodyProxy(body, target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn target[prop]\n\t\t}\n\t})\n}\n\nfunction getResponseParams(res, current)\n{\n\t// function to fetch all relevant properties of a Response\n\tlet params = current || {}\n\tif (!params.url && current.url) {\n\t\tparams.url = current.url\n\t}\n\tfor(let prop of ['status','statusText','headers','body','url','type','redirected']) {\n\t\tif (typeof res[prop] == 'function') {\n\t\t\tres[prop](params[prop], params)\n\t\t} else if (typeof res[prop] != 'undefined') {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = new URL(res.url, params.url || 'https://localhost/')\n\t\t\t} else {\n\t\t\t\tparams[prop] = res[prop]\n\t\t\t}\n\t\t}\n\t}\n\treturn params\n}\n\n/**\n * @typedef {Response} MetroResponse\n * @property {Symbol(source)} - returns the target Response of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroResponse, with the given options added\n * @param {} ...options - respomse options, handled in order\n * \n * Returns a new metro Response object\n * @param {} ...options - request options, handled in order\n * @return {MetroResponse} - a new metro Response object\n */\nexport function response(...options)\n{\n\tlet responseParams = {}\n\tfor (let option of options) {\n\t\tif (typeof option == 'string') {\n\t\t\tresponseParams.body = option\n\t\t} else if (option instanceof Response) {\n\t\t\tObject.assign(responseParams, getResponseParams(option, responseParams))\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tif (option instanceof FormData\n\t\t\t\t|| option instanceof Blob\n\t\t\t\t|| option instanceof ArrayBuffer\n\t\t\t\t|| option instanceof DataView\n\t\t\t\t|| option instanceof ReadableStream\n\t\t\t\t|| option instanceof URLSearchParams\n\t\t\t\t|| option instanceof String\n\t\t\t\t|| (typeof TypedArray != 'undefined' && option instanceof TypedArray)\n\t\t\t) {\n\t\t\t\tresponseParams.body = option\n\t\t\t} else {\n\t\t\t\tObject.assign(responseParams, getResponseParams(option, responseParams))\n\t\t\t}\n\t\t}\n\t}\n\tlet r = new Response(responseParams.body, responseParams)\t\n\tObject.freeze(r)\n\treturn new Proxy(r, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\treturn response(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'body':\n\t\t\t\t\tif (responseParams.body) {\n\t\t\t\t\t\tif (responseParams.body[symbols.isProxy]) {\n\t\t\t\t\t\t\treturn responseParams.body\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn bodyProxy(responseParams.body, target)\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn bodyProxy('',target)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'ok':\n\t\t\t\t\treturn (target.status>=200) && (target.status<400)\n\t\t\t\tbreak\n\t\t\t\tcase 'headers':\n\t\t\t\t\treturn target.headers\n\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\tif (prop in responseParams && prop != 'toString') {\n\t\t\t\t\t\treturn responseParams[prop]\n\t\t\t\t\t}\n\t\t\t\t\tif (prop in target && prop != 'toString') {\n\t\t\t\t\t\t// skipped toString, since it has no usable output\n\t\t\t\t\t\t// and body may have its own toString\n\t\t\t\t\t\tif (typeof target[prop] == 'function') {\n\t\t\t\t\t\t\treturn function(...args) {\n\t\t\t\t\t\t\t\treturn target[prop].apply(target, args)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn target[prop]\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn undefined\n\t\t}\n\t})\n}\n\nfunction appendSearchParams(url, params) {\n\tif (typeof params == 'function') {\n\t\t params(url.searchParams, url)\n\t} else {\n\t\tparams = new URLSearchParams(params)\n\t\tparams.forEach((value,key) => {\n\t\t\turl.searchParams.append(key, value)\n\t\t})\n\t}\n}\n\n/**\n * @typedef {URL} MetroURL\n * @property {Symbol(source)} - returns the target Request of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroRequest, with the given options added\n * @param {} ...options - url options, handled in order\n * \n * Returns a new metro URL object\n * @param {} ...options - url options, handled in order\n * @return {MetroURL} - a new metro URL object\n */\nexport function url(...options)\n{\n\tlet validParams = ['hash','host','hostname','href',\n\t\t\t'password','pathname','port','protocol','username','search','searchParams']\n\tlet u = new URL('https://localhost/')\n\tfor (let option of options) {\n\t\tif (typeof option == 'string' || option instanceof String) {\n\t\t\t// option is a relative or absolute url\n\t\t\tu = new URL(option, u)\n\t\t} else if (option instanceof URL \n\t\t\t|| (typeof Location != 'undefined' \n\t\t\t\t&& option instanceof Location)\n\t\t) {\n\t\t\tu = new URL(option)\n\t\t} else if (option instanceof URLSearchParams) {\n\t\t\tappendSearchParams(u, option)\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tfor (let param in option) {\n\t\t\t\tif (param=='search') {\n\t\t\t\t\tif (typeof option.search == 'function') {\n\t\t\t\t\t\toption.search(u.search, u)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tu.search = new URLSearchParams(option.search)\n\t\t\t\t\t}\n\t\t\t\t} else if (param=='searchParams') {\n\t\t\t\t\tappendSearchParams(u, option.searchParams)\n\t\t\t\t} else {\n\t\t\t\t\tif (!validParams.includes(param)) {\n\t\t\t\t\t\tthrow metroError('metro.url: unknown url parameter '+metroURL+'url/unknown-param-name/', param)\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof option[param] == 'function') {\n\t\t\t\t\t\toption[param](u[param], u)\n\t\t\t\t\t} else if (\n\t\t\t\t\t\ttypeof option[param] == 'string' || option[param] instanceof String \n\t\t\t\t\t\t|| typeof option[param] == 'number' || option[param] instanceof Number\n\t\t\t\t\t\t|| typeof option[param] == 'boolean' || option[param] instanceof Boolean\n\t\t\t\t\t) {\n\t\t\t\t\t\tu[param] = ''+option[param]\n\t\t\t\t\t} else if (typeof option[param] == 'object' && option[param].toString) {\n\t\t\t\t\t\tu[param] = option[param].toString()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow metroError('metro.url: unsupported value for '+param+' '+metroURL+'url/unsupported-param-value/', options[param])\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow metroError('metro.url: unsupported option value '+metroURL+'url/unsupported-option-value/', option)\n\t\t}\n\t}\n\tObject.freeze(u)\n\treturn new Proxy(u, {\n\t\tget(target, prop, receiver) {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\treturn url(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\tcase 'toString':\n\t\t\t\tcase 'toJSON':\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\treturn target[prop]()\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn target[prop]\n\t\t}\n\t})\n}\n\n/**\n * @typedef {FormData} MetroFormData\n * @property {Symbol(source)} - returns the target Request of this Proxy\n * @property {Symbol(isProxy)} - returns true\n * @method with - returns a new MetroRequest, with the given options added\n * @param {} ...options - url options, handled in order\n * \n * Returns a new metro FormData object\n * @param {} ...options - formdata options, handled in order\n * @return {MetroURL} - a new metro FormData object\n */\nexport function formdata(...options)\n{\n\tvar params = new FormData()\n\tfor (let option of options) {\n\t\tif (option instanceof FormData) {\n\t\t\tfor (let entry of option.entries()) {\n\t\t\t\tparams.append(entry[0],entry[1])\n\t\t\t}\n\t\t} else if (option && typeof option == 'object') {\n\t\t\tfor (let entry of Object.entries(option)) {\n\t\t\t\tif (Array.isArray(entry[1])) {\n\t\t\t\t\tfor (let value of entry[1]) {\n\t\t\t\t\t\tparams.append(entry[0], value)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tparams.append(entry[0],entry[1])\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new metroError('metro.formdata: unknown option type, only FormData or Object supported',option)\n\t\t}\n\t}\n\tObject.freeze(params)\n\treturn new Proxy(params, {\n\t\tget: (target,prop,receiver) => {\n\t\t\tswitch(prop) {\n\t\t\t\tcase symbols.isProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase symbols.source:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase 'with':\n\t\t\t\t\treturn function(...options) {\n\t\t\t\t\t\treturn formdata(target, ...options)\n\t\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t\t// case 'toString':\n\t\t\t\t// case 'toJSON':\n\t\t\t\t// \treturn function() {\n\t\t\t\t// \t\treturn target[prop]()\n\t\t\t\t// \t}\n\t\t\t\t// break\n\t\t\t}\n\t\t\treturn target[prop]\n\t\t}\n\t})\n}\n\nconst metroConsole = {\n\terror: (message, ...details) => {\n\t\tconsole.error('Ⓜ️ ',message, ...details)\n\t},\n\tinfo: (message, ...details) => {\n\t\tconsole.info('Ⓜ️ ',message, ...details)\n\t},\n\tgroup: (name) => {\n\t\tconsole.group('Ⓜ️ '+name)\n\t},\n\tgroupEnd: (name) => {\n\t\tconsole.groupEnd('Ⓜ️ '+name)\n\t}\n}\n\n\n/**\n * Custom Metro Error function that outputs to the console then throws an error\n */\nexport function metroError(message, ...details) {\n\tmetroConsole.error(message, ...details)\n\treturn new Error(message, ...details)\n}\n\n/**\n * Set of debugging tools to trace the request - response flow\n * Tracer are run on all metro fetch calls\n */\nexport const trace = {\n\t/**\n\t * Adds a named tracer function\n\t * @param {string} name - the name of the tracer\n\t * @param {Function} tracer - the tracer function to call\n\t */\n\tadd(name, tracer) {\n\t\tClient.tracers[name] = tracer\n\t},\n\t/**\n\t * Removes a named tracer function\n\t * @param {string} name\n\t */\n\tdelete(name) {\n\t\tdelete Client.tracers[name]\n\t},\n\t/**\n\t * Removes all tracer functions\n\t */\n\tclear() {\n\t\tClient.tracers = {}\n\t},\n\t/**\n\t * Returns a set of request and response tracer functions that use the\n\t * console.group feature to shows nested request/response pairs, with\n\t * most commonly needed information for debugging\n\t */\n\tgroup() {\n\t\tlet group = 0;\n\t\treturn {\n\t\t\trequest: (req, middleware) => {\n\t\t\t\tgroup++\n\t\t\t\tmetroConsole.group(group)\n\t\t\t\tmetroConsole.info(req?.url, req, middleware)\n\t\t\t},\n\t\t\tresponse: (res, middleware) => {\n\t\t\t\tmetroConsole.info(res?.body ? res.body[symbols.source]: null, res, middleware)\n\t\t\t\tmetroConsole.groupEnd(group)\n\t\t\t\tgroup--\n\t\t\t}\n\t\t}\n\t}\n}\n","import * as metro from './metro.mjs'\nimport jsonmw from './mw/json.mjs'\nimport thrower from './mw/thrower.mjs'\n\nwindow.metro = Object.assign({}, metro, {\n\tmw: {\n\t\tjsonmw,\n\t\tthrower\n\t}\n})","import * as metro from '../metro.mjs'\n\nexport default function jsonmw(options) {\n\toptions = Object.assign({\n\t\treviver: null,\n\t\treplacer: null,\n\t\tspace: ''\n\t}, options)\n\n\treturn async (req, next) => {\n\t\tif (['POST','PUT','PATCH','QUERY'].includes(req.method)) {\n\t\t\treq = req.with({\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type':'application/json',\n\t 'Accept':'application/json'\n\t\t\t\t}\n\t\t\t})\n\t\t\tif (req.body && typeof req.body[metro.symbols.source] == 'object') {\n\t\t\t\treq = req.with({\n\t\t\t\t\tbody: JSON.stringify(req.body[metro.symbols.source], options.replacer, options.space)\n\t\t\t\t})\n\t\t\t}\n\t\t} else {\n\t\t\treq = req.with({\n\t\t\t\theaders: {\n\t\t\t 'Accept':'application/json'\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\tlet res = await next(req)\n\t\tlet body = await res.text()\n\t\tlet json = JSON.parse(body, options.reviver)\n\t\treturn res.with({\n\t\t\tbody: json\n\t\t})\n\t}\n}","import * as metro from '../metro.mjs'\n\nexport default function thrower(options) {\n\n\treturn async (req, next) => {\n\t\tlet res = await next(req)\n\t\tif (!res.ok) {\n\t\t\tif (options && typeof options[res.status] == 'function') {\n\t\t\t\tres = options[res.status].apply(res, req)\n\t\t\t} else {\n\t\t\t\tthrow new Error(res.status+': '+res.statusText, {\n\t\t\t\t\tcause: res\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\treturn res\n\t}\n\n}"],"names":["$parcel$export","e","n","v","s","Object","defineProperty","get","set","enumerable","configurable","$parcel$global","globalThis","$parcel$modules","$parcel$inits","parcelRequire","id","exports","init","module","call","err","Error","code","register","parcelRegister","$86c8ab3a59b0bae1$export$47616e9f7f5fe113","$86c8ab3a59b0bae1$export$b5fe3f66a567bec0","$86c8ab3a59b0bae1$export$7079e2c78c274c66","$86c8ab3a59b0bae1$export$785bb8ef7fad1f74","$86c8ab3a59b0bae1$export$388e0302ca0d9a41","$86c8ab3a59b0bae1$export$128fa18b7194ef","$86c8ab3a59b0bae1$export$5de500aade6bf050","options","params","FormData","option","entry","entries","append","Array","isArray","value","freeze","Proxy","target","prop","receiver","isProxy","source","$86c8ab3a59b0bae1$export$357889f174732d38","$86c8ab3a59b0bae1$var$metroURL","Symbol","$86c8ab3a59b0bae1$var$Client","url","window","location","tracers","constructor","String","assign","Function","param","verb","verbs","fetch","method","toUpperCase","middlewares","index","findIndex","m","concat","req","next","toLowerCase","slice","middleware","res","values","tracer","request","response","with","$86c8ab3a59b0bae1$var$bodyProxy","body","r","ReadableStream","Blob","stream","start","controller","chunk","toString","URLSearchParams","ArrayBuffer","isView","enqueue","close","args","apply","has","ownKeys","Reflect","getOwnPropertyDescriptor","requestParams","duplex","URL","DataView","$86c8ab3a59b0bae1$var$getRequestParams","current","key","headers","Headers","TypedArray","JSON","stringify","Request","unshift","$86c8ab3a59b0bae1$var$getResponseParams","responseParams","Response","status","$86c8ab3a59b0bae1$var$appendSearchParams","searchParams","forEach","validParams","u","Location","search","includes","Number","Boolean","message","details","console","error","info","name","group","groupEnd","$86c8ab3a59b0bae1$var$metroConsole","add","delete","clear","$hkeot","metro","mw","jsonmw","reviver","replacer","space","symbols","json","parse","text","thrower","ok","statusText","cause"],"version":3,"file":"everything.js.map","sourceRoot":"../"} \ No newline at end of file diff --git a/package.json b/package.json index 04d6141..5272dee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@muze-nl/metro", - "version": "0.4.3", + "version": "0.4.4", "description": "http client with middleware support", "type": "module", "source": [ "src/browser.mjs", "src/everything.mjs" ],