diff --git a/dist/browser.js b/dist/browser.js index 0686439..df2d9d3 100644 --- a/dist/browser.js +++ b/dist/browser.js @@ -1,2 +1,641 @@ -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; +(() => { + var __defProp = Object.defineProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + + // src/metro.mjs + var metro_exports = {}; + __export(metro_exports, { + client: () => client, + formdata: () => formdata, + metroError: () => metroError, + request: () => request, + response: () => response, + trace: () => trace, + url: () => url + }); + var metroURL = "https://metro.muze.nl/details/"; + if (!Symbol.metroProxy) { + Symbol.metroProxy = Symbol("isProxy"); + } + if (!Symbol.metroSource) { + Symbol.metroSource = Symbol("source"); + } + var Client = class _Client { + #options = { + url: typeof window != "undefined" ? window.location : "https://localhost" + }; + #verbs = ["get", "post", "put", "delete", "patch", "head", "options", "query"]; + static tracers = {}; + /** + * @typedef {Object} ClientOptions + * @property {Array} middlewares - list of middleware functions + * @property {string|URL} url - default url of the client + * @property {[string]} verbs - a list of verb methods to expose, e.g. ['get','post'] + * + * Constructs a new metro client. Can have any number of params. + * @params {ClientOptions|URL|Function|Client} + * @returns {Client} - A metro client object with given or default verb methods + */ + constructor(...options) { + for (let option of options) { + if (typeof option == "string" || option instanceof String) { + this.#options.url = "" + option; + } else if (option instanceof _Client) { + Object.assign(this.#options, option.#options); + } else if (option instanceof Function) { + this.#addMiddlewares([option]); + } else if (option && typeof option == "object") { + for (let param in option) { + if (param == "middlewares") { + this.#addMiddlewares(option[param]); + } else if (typeof option[param] == "function") { + this.#options[param] = option[param](this.#options[param], this.#options); + } else { + this.#options[param] = option[param]; + } + } + } + } + if (this.#options.verbs) { + this.#verbs = this.#options.verbs; + delete this.#options.verbs; + } + for (const verb of this.#verbs) { + this[verb] = async function(...options2) { + return this.fetch(request( + this.#options, + ...options2, + { method: verb.toUpperCase() } + )); + }; + } + Object.freeze(this); + } + #addMiddlewares(middlewares) { + if (typeof middlewares == "function") { + middlewares = [middlewares]; + } + let index = middlewares.findIndex((m) => typeof m != "function"); + if (index >= 0) { + throw metroError("metro.client: middlewares must be a function or an array of functions " + metroURL + "client/invalid-middlewares-value/", middlewares[index]); + } + if (!Array.isArray(this.#options.middlewares)) { + this.#options.middlewares = []; + } + this.#options.middlewares = this.#options.middlewares.concat(middlewares); + } + /** + * Mimics the standard browser fetch method, but uses any middleware installed through + * the constructor. + * @param {Request|string|Object} - Required. The URL or Request object, accepts all types that are accepted by metro.request + * @param {Object} - Optional. Any object that is accepted by metro.request + * @return {Promise} - The metro.response to this request, or any other result as changed by any included middleware. + */ + fetch(req, options) { + req = request(req, options); + if (!req.url) { + throw metroError("metro.client." + req.method.toLowerCase() + ": Missing url parameter " + metroURL + "client/missing-url-param/", req); + } + if (!options) { + options = {}; + } + if (!(typeof options === "object") || Array.isArray(options) || options instanceof String) { + throw metroError("metro.client.fetch: Options is not an object"); + } + const metrofetch = async function browserFetch(req2) { + if (req2[Symbol.metroProxy]) { + if (req2.body) { + try { + let r = req2.with(); + let f = await r.formData(); + console.log("hier", f); + } catch (e) { + } + } + req2 = req2[Symbol.metroSource]; + } + const res = await fetch(req2); + return response(res); + }; + let middlewares = [metrofetch].concat(this.#options?.middlewares?.slice() || []); + options = Object.assign({}, this.#options, options); + let next; + for (let middleware of middlewares) { + next = /* @__PURE__ */ function(next2, middleware2) { + return async function(req2) { + let res; + let tracers = Object.values(_Client.tracers); + for (let tracer of tracers) { + if (tracer.request) { + tracer.request.call(tracer, req2, middleware2); + } + } + res = await middleware2(req2, next2); + for (let tracer of tracers) { + if (tracer.response) { + tracer.response.call(tracer, res, middleware2); + } + } + return res; + }; + }(next, middleware); + } + return next(req); + } + with(...options) { + return new _Client(this, ...options); + } + }; + function client(...options) { + return new Client(...options); + } + function bodyProxy(body, r) { + let source = r.body; + if (!source) { + if (body === null) { + source = new ReadableStream(); + } else if (body instanceof ReadableStream) { + source = body; + } else if (body instanceof Blob) { + source = body.stream(); + } else { + source = new ReadableStream({ + start(controller) { + let chunk; + switch (typeof body) { + case "object": + if (typeof body.toString == "function") { + chunk = body.toString(); + } else if (body instanceof FormData) { + chunk = new URLSearchParams(body).toString(); + } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) { + chunk = body; + } else { + throw metroError("Cannot convert body to ReadableStream", body); + } + break; + case "string": + case "number": + case "boolean": + chunk = body; + break; + default: + throw metroError("Cannot convert body to ReadableStream", body); + break; + } + controller.enqueue(chunk); + controller.close(); + } + }); + } + } + return new Proxy(source, { + get(target, prop, receiver) { + switch (prop) { + case Symbol.metroProxy: + return true; + break; + case Symbol.metroSource: + return body; + break; + case "toString": + return function() { + return "" + body; + }; + break; + } + if (body && typeof body == "object") { + if (prop in body) { + if (typeof body[prop] == "function") { + return function(...args) { + return body[prop].apply(body, args); + }; + } + return body[prop]; + } + } + if (prop in target && prop != "toString") { + if (typeof target[prop] == "function") { + return function(...args) { + return target[prop].apply(target, args); + }; + } + return target[prop]; + } + }, + has(target, prop) { + if (body && typeof body == "object") { + return prop in body; + } else { + return prop in target; + } + }, + ownKeys(target) { + if (body && typeof body == "object") { + return Reflect.ownKeys(body); + } else { + return Reflect.ownKeys(target); + } + }, + getOwnPropertyDescriptor(target, prop) { + if (body && typeof body == "object") { + return Object.getOwnPropertyDescriptor(body, prop); + } else { + return Object.getOwnPropertyDescriptor(target, prop); + } + } + }); + } + function getRequestParams(req, current) { + let params = current || {}; + if (!params.url && current.url) { + params.url = current.url; + } + for (let prop of [ + "method", + "headers", + "body", + "mode", + "credentials", + "cache", + "redirect", + "referrer", + "referrerPolicy", + "integrity", + "keepalive", + "signal", + "priority", + "url" + ]) { + if (typeof req[prop] == "function") { + req[prop](params[prop], params); + } else if (typeof req[prop] != "undefined") { + if (prop == "url") { + params.url = url(params.url, req.url); + } else if (prop == "headers") { + params.headers = new Headers(current.headers); + if (!(req.headers instanceof Headers)) { + req.headers = new Headers(req.headers); + } + for (let [key, value] of req.headers.entries()) { + params.headers.set(key, value); + } + } else { + params[prop] = req[prop]; + } + } + } + return params; + } + function request(...options) { + let requestParams = { + url: typeof window != "undefined" ? window.location : "https://localhost/", + duplex: "half" + // required when setting body to ReadableStream, just set it here by default already + }; + for (let option of options) { + if (typeof option == "string" || option instanceof URL || option instanceof URLSearchParams) { + requestParams.url = url(requestParams.url, option); + } else if (option && (option instanceof FormData || option instanceof ReadableStream || option instanceof Blob || option instanceof ArrayBuffer || option instanceof DataView)) { + requestParams.body = option; + } else if (option && typeof option == "object") { + Object.assign(requestParams, getRequestParams(option, requestParams)); + } + } + let body = requestParams.body; + if (body) { + 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); + } + } + let r = new Request(requestParams.url, requestParams); + Object.freeze(r); + return new Proxy(r, { + get(target, prop, receiver) { + switch (prop) { + case Symbol.metroSsource: + return target; + break; + case Symbol.metroProxy: + return true; + break; + case "with": + return function(...options2) { + if (body) { + options2.unshift({ body }); + } + return request(target, ...options2); + }; + break; + case "toString": + case "toJSON": + return function() { + return target[prop].apply(target); + }; + break; + case "blob": + case "text": + case "json": + return function() { + return target[prop].apply(target); + }; + break; + case "body": + if (!body) { + body = target.body; + } + if (body) { + if (body[Symbol.metroProxy]) { + return body; + } + return bodyProxy(body, target); + } + break; + } + if (target[prop] instanceof Function) { + return target[prop].bind(target); + } + return target[prop]; + } + }); + } + function getResponseParams(res, current) { + let params = current || {}; + if (!params.url && current.url) { + params.url = current.url; + } + for (let prop of ["status", "statusText", "headers", "body", "url", "type", "redirected"]) { + if (typeof res[prop] == "function") { + res[prop](params[prop], params); + } else if (typeof res[prop] != "undefined") { + if (prop == "url") { + params.url = new URL(res.url, params.url || "https://localhost/"); + } else { + params[prop] = res[prop]; + } + } + } + return params; + } + function response(...options) { + let responseParams = {}; + for (let option of options) { + if (typeof option == "string") { + responseParams.body = option; + } else if (option instanceof Response) { + Object.assign(responseParams, getResponseParams(option, responseParams)); + } else if (option && typeof option == "object") { + 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; + } else { + Object.assign(responseParams, getResponseParams(option, responseParams)); + } + } + } + let r = new Response(responseParams.body, responseParams); + Object.freeze(r); + return new Proxy(r, { + get(target, prop, receiver) { + switch (prop) { + case Symbol.metroProxy: + return true; + break; + case Symbol.metroSource: + return target; + break; + case "with": + return function(...options2) { + return response(target, ...options2); + }; + break; + case "body": + if (responseParams.body) { + if (responseParams.body[Symbol.metroProxy]) { + return responseParams.body; + } + return bodyProxy(responseParams.body, target); + } else { + return bodyProxy("", target); + } + break; + case "ok": + return target.status >= 200 && target.status < 400; + break; + case "headers": + return target.headers; + break; + default: + if (prop in responseParams && prop != "toString") { + return responseParams[prop]; + } + if (prop in target && prop != "toString") { + if (typeof target[prop] == "function") { + return function(...args) { + return target[prop].apply(target, args); + }; + } + return target[prop]; + } + break; + } + return void 0; + } + }); + } + function appendSearchParams(url2, params) { + if (typeof params == "function") { + params(url2.searchParams, url2); + } else { + params = new URLSearchParams(params); + params.forEach((value, key) => { + url2.searchParams.append(key, value); + }); + } + } + function url(...options) { + let validParams = [ + "hash", + "host", + "hostname", + "href", + "password", + "pathname", + "port", + "protocol", + "username", + "search", + "searchParams" + ]; + let u = new URL("https://localhost/"); + for (let option of options) { + if (typeof option == "string" || option instanceof String) { + u = new URL(option, u); + } else if (option instanceof URL || typeof Location != "undefined" && option instanceof Location) { + u = new URL(option); + } else if (option instanceof URLSearchParams) { + appendSearchParams(u, option); + } else if (option && typeof option == "object") { + for (let param in option) { + if (param == "search") { + if (typeof option.search == "function") { + option.search(u.search, u); + } else { + u.search = new URLSearchParams(option.search); + } + } else if (param == "searchParams") { + appendSearchParams(u, option.searchParams); + } else { + if (!validParams.includes(param)) { + throw metroError("metro.url: unknown url parameter " + metroURL + "url/unknown-param-name/", param); + } + if (typeof option[param] == "function") { + option[param](u[param], u); + } 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]; + } else if (typeof option[param] == "object" && option[param].toString) { + u[param] = option[param].toString(); + } else { + throw metroError("metro.url: unsupported value for " + param + " " + metroURL + "url/unsupported-param-value/", options[param]); + } + } + } + } else { + throw metroError("metro.url: unsupported option value " + metroURL + "url/unsupported-option-value/", option); + } + } + Object.freeze(u); + return new Proxy(u, { + get(target, prop, receiver) { + switch (prop) { + case Symbol.metroProxy: + return true; + break; + case Symbol.metroSource: + return target; + break; + case "with": + return function(...options2) { + return url(target, ...options2); + }; + break; + case "toString": + case "toJSON": + return function() { + return target[prop](); + }; + break; + } + return target[prop]; + } + }); + } + function formdata(...options) { + var params = new FormData(); + for (let option of options) { + if (option instanceof FormData) { + for (let entry of option.entries()) { + params.append(entry[0], entry[1]); + } + } else if (option && typeof option == "object") { + for (let entry of Object.entries(option)) { + if (Array.isArray(entry[1])) { + for (let value of entry[1]) { + params.append(entry[0], value); + } + } else { + params.append(entry[0], entry[1]); + } + } + } else { + throw new metroError("metro.formdata: unknown option type, only FormData or Object supported", option); + } + } + Object.freeze(params); + return new Proxy(params, { + get: (target, prop, receiver) => { + switch (prop) { + case Symbol.metroProxy: + return true; + break; + case Symbol.metroSource: + return target; + break; + case "with": + return function(...options2) { + return formdata(target, ...options2); + }; + break; + } + return target[prop]; + } + }); + } + var metroConsole = { + error: (message, ...details) => { + console.error("\u24C2\uFE0F ", message, ...details); + }, + info: (message, ...details) => { + console.info("\u24C2\uFE0F ", message, ...details); + }, + group: (name) => { + console.group("\u24C2\uFE0F " + name); + }, + groupEnd: (name) => { + console.groupEnd("\u24C2\uFE0F " + name); + } + }; + function metroError(message, ...details) { + metroConsole.error(message, ...details); + return new Error(message, ...details); + } + var trace = { + /** + * Adds a named tracer function + * @param {string} name - the name of the tracer + * @param {Function} tracer - the tracer function to call + */ + add(name, tracer) { + Client.tracers[name] = tracer; + }, + /** + * Removes a named tracer function + * @param {string} name + */ + delete(name) { + delete Client.tracers[name]; + }, + /** + * Removes all tracer functions + */ + clear() { + Client.tracers = {}; + }, + /** + * Returns a set of request and response tracer functions that use the + * console.group feature to shows nested request/response pairs, with + * most commonly needed information for debugging + */ + group() { + let group = 0; + return { + request: (req, middleware) => { + group++; + metroConsole.group(group); + metroConsole.info(req?.url, req, middleware); + }, + response: (res, middleware) => { + metroConsole.info(res?.body ? res.body[Symbol.metroSource] : null, res, middleware); + metroConsole.groupEnd(group); + group--; + } + }; + } + }; + + // src/browser.mjs + window.metro = metro_exports; +})(); //# sourceMappingURL=browser.js.map diff --git a/dist/browser.js.map b/dist/browser.js.map index dbb9627..99f4c25 100644 --- a/dist/browser.js.map +++ b/dist/browser.js.map @@ -1 +1,7 @@ -{"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 +{ + "version": 3, + "sources": ["../src/metro.mjs", "../src/browser.mjs"], + "sourcesContent": ["/**\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 */\nif (!Symbol.metroProxy) {\n\tSymbol.metroProxy = Symbol('isProxy')\n}\nif (!Symbol.metroSource) {\n\tSymbol.metroSource = 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[Symbol.metroProxy]) {\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\tif (req.body) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlet r = req.with()\n\t\t\t\t\t\tlet f = await r.formData()\n\t\t\t\t\t\tconsole.log('hier',f)\n\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t// ignore\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treq = req[Symbol.metroSource]\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 Symbol.metroProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase Symbol.metroSource:\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 (body && 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\tif (body && typeof body == 'object') {\n\t\t\t\treturn prop in body\n\t\t\t} else {\n\t\t\t\treturn prop in target\n\t\t\t}\n\t\t},\n\t\townKeys(target) {\n\t\t\tif (body && typeof body == 'object') {\n\t\t\t\treturn Reflect.ownKeys(body)\n\t\t\t} else {\n\t\t\t\treturn Reflect.ownKeys(target)\n\t\t\t}\n\t\t},\n\t\tgetOwnPropertyDescriptor(target, prop) {\n\t\t\tif (body && typeof body == 'object') {\n\t\t\t\treturn Object.getOwnPropertyDescriptor(body,prop)\n\t\t\t} else {\n\t\t\t\treturn Object.getOwnPropertyDescriptor(target,prop)\n\t\t\t}\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 Symbol.metroSsource:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase Symbol.metroProxy:\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[Symbol.metroProxy]) {\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\tif (target[prop] instanceof Function) {\n\t\t\t\treturn target[prop].bind(target)\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 Symbol.metroProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase Symbol.metroSource:\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[Symbol.metroProxy]) {\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 Symbol.metroProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase Symbol.metroSource:\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 Symbol.metroProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase Symbol.metroSource:\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('\u24C2\uFE0F ',message, ...details)\n\t},\n\tinfo: (message, ...details) => {\n\t\tconsole.info('\u24C2\uFE0F ',message, ...details)\n\t},\n\tgroup: (name) => {\n\t\tconsole.group('\u24C2\uFE0F '+name)\n\t},\n\tgroupEnd: (name) => {\n\t\tconsole.groupEnd('\u24C2\uFE0F '+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[Symbol.metroSource]: 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"], + "mappings": "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", + "names": ["options", "req", "next", "middleware", "options", "url"] +} diff --git a/dist/everything.js b/dist/everything.js index b52bc8a..246c603 100644 --- a/dist/everything.js +++ b/dist/everything.js @@ -1,2 +1,699 @@ -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}}}}); +(() => { + var __defProp = Object.defineProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + + // src/metro.mjs + var metro_exports = {}; + __export(metro_exports, { + client: () => client, + formdata: () => formdata, + metroError: () => metroError, + request: () => request, + response: () => response, + trace: () => trace, + url: () => url + }); + var metroURL = "https://metro.muze.nl/details/"; + if (!Symbol.metroProxy) { + Symbol.metroProxy = Symbol("isProxy"); + } + if (!Symbol.metroSource) { + Symbol.metroSource = Symbol("source"); + } + var Client = class _Client { + #options = { + url: typeof window != "undefined" ? window.location : "https://localhost" + }; + #verbs = ["get", "post", "put", "delete", "patch", "head", "options", "query"]; + static tracers = {}; + /** + * @typedef {Object} ClientOptions + * @property {Array} middlewares - list of middleware functions + * @property {string|URL} url - default url of the client + * @property {[string]} verbs - a list of verb methods to expose, e.g. ['get','post'] + * + * Constructs a new metro client. Can have any number of params. + * @params {ClientOptions|URL|Function|Client} + * @returns {Client} - A metro client object with given or default verb methods + */ + constructor(...options) { + for (let option of options) { + if (typeof option == "string" || option instanceof String) { + this.#options.url = "" + option; + } else if (option instanceof _Client) { + Object.assign(this.#options, option.#options); + } else if (option instanceof Function) { + this.#addMiddlewares([option]); + } else if (option && typeof option == "object") { + for (let param in option) { + if (param == "middlewares") { + this.#addMiddlewares(option[param]); + } else if (typeof option[param] == "function") { + this.#options[param] = option[param](this.#options[param], this.#options); + } else { + this.#options[param] = option[param]; + } + } + } + } + if (this.#options.verbs) { + this.#verbs = this.#options.verbs; + delete this.#options.verbs; + } + for (const verb of this.#verbs) { + this[verb] = async function(...options2) { + return this.fetch(request( + this.#options, + ...options2, + { method: verb.toUpperCase() } + )); + }; + } + Object.freeze(this); + } + #addMiddlewares(middlewares) { + if (typeof middlewares == "function") { + middlewares = [middlewares]; + } + let index = middlewares.findIndex((m) => typeof m != "function"); + if (index >= 0) { + throw metroError("metro.client: middlewares must be a function or an array of functions " + metroURL + "client/invalid-middlewares-value/", middlewares[index]); + } + if (!Array.isArray(this.#options.middlewares)) { + this.#options.middlewares = []; + } + this.#options.middlewares = this.#options.middlewares.concat(middlewares); + } + /** + * Mimics the standard browser fetch method, but uses any middleware installed through + * the constructor. + * @param {Request|string|Object} - Required. The URL or Request object, accepts all types that are accepted by metro.request + * @param {Object} - Optional. Any object that is accepted by metro.request + * @return {Promise} - The metro.response to this request, or any other result as changed by any included middleware. + */ + fetch(req, options) { + req = request(req, options); + if (!req.url) { + throw metroError("metro.client." + req.method.toLowerCase() + ": Missing url parameter " + metroURL + "client/missing-url-param/", req); + } + if (!options) { + options = {}; + } + if (!(typeof options === "object") || Array.isArray(options) || options instanceof String) { + throw metroError("metro.client.fetch: Options is not an object"); + } + const metrofetch = async function browserFetch(req2) { + if (req2[Symbol.metroProxy]) { + if (req2.body) { + try { + let r = req2.with(); + let f = await r.formData(); + console.log("hier", f); + } catch (e) { + } + } + req2 = req2[Symbol.metroSource]; + } + const res = await fetch(req2); + return response(res); + }; + let middlewares = [metrofetch].concat(this.#options?.middlewares?.slice() || []); + options = Object.assign({}, this.#options, options); + let next; + for (let middleware of middlewares) { + next = /* @__PURE__ */ function(next2, middleware2) { + return async function(req2) { + let res; + let tracers = Object.values(_Client.tracers); + for (let tracer of tracers) { + if (tracer.request) { + tracer.request.call(tracer, req2, middleware2); + } + } + res = await middleware2(req2, next2); + for (let tracer of tracers) { + if (tracer.response) { + tracer.response.call(tracer, res, middleware2); + } + } + return res; + }; + }(next, middleware); + } + return next(req); + } + with(...options) { + return new _Client(this, ...options); + } + }; + function client(...options) { + return new Client(...options); + } + function bodyProxy(body, r) { + let source = r.body; + if (!source) { + if (body === null) { + source = new ReadableStream(); + } else if (body instanceof ReadableStream) { + source = body; + } else if (body instanceof Blob) { + source = body.stream(); + } else { + source = new ReadableStream({ + start(controller) { + let chunk; + switch (typeof body) { + case "object": + if (typeof body.toString == "function") { + chunk = body.toString(); + } else if (body instanceof FormData) { + chunk = new URLSearchParams(body).toString(); + } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) { + chunk = body; + } else { + throw metroError("Cannot convert body to ReadableStream", body); + } + break; + case "string": + case "number": + case "boolean": + chunk = body; + break; + default: + throw metroError("Cannot convert body to ReadableStream", body); + break; + } + controller.enqueue(chunk); + controller.close(); + } + }); + } + } + return new Proxy(source, { + get(target, prop, receiver) { + switch (prop) { + case Symbol.metroProxy: + return true; + break; + case Symbol.metroSource: + return body; + break; + case "toString": + return function() { + return "" + body; + }; + break; + } + if (body && typeof body == "object") { + if (prop in body) { + if (typeof body[prop] == "function") { + return function(...args) { + return body[prop].apply(body, args); + }; + } + return body[prop]; + } + } + if (prop in target && prop != "toString") { + if (typeof target[prop] == "function") { + return function(...args) { + return target[prop].apply(target, args); + }; + } + return target[prop]; + } + }, + has(target, prop) { + if (body && typeof body == "object") { + return prop in body; + } else { + return prop in target; + } + }, + ownKeys(target) { + if (body && typeof body == "object") { + return Reflect.ownKeys(body); + } else { + return Reflect.ownKeys(target); + } + }, + getOwnPropertyDescriptor(target, prop) { + if (body && typeof body == "object") { + return Object.getOwnPropertyDescriptor(body, prop); + } else { + return Object.getOwnPropertyDescriptor(target, prop); + } + } + }); + } + function getRequestParams(req, current) { + let params = current || {}; + if (!params.url && current.url) { + params.url = current.url; + } + for (let prop of [ + "method", + "headers", + "body", + "mode", + "credentials", + "cache", + "redirect", + "referrer", + "referrerPolicy", + "integrity", + "keepalive", + "signal", + "priority", + "url" + ]) { + if (typeof req[prop] == "function") { + req[prop](params[prop], params); + } else if (typeof req[prop] != "undefined") { + if (prop == "url") { + params.url = url(params.url, req.url); + } else if (prop == "headers") { + params.headers = new Headers(current.headers); + if (!(req.headers instanceof Headers)) { + req.headers = new Headers(req.headers); + } + for (let [key, value] of req.headers.entries()) { + params.headers.set(key, value); + } + } else { + params[prop] = req[prop]; + } + } + } + return params; + } + function request(...options) { + let requestParams = { + url: typeof window != "undefined" ? window.location : "https://localhost/", + duplex: "half" + // required when setting body to ReadableStream, just set it here by default already + }; + for (let option of options) { + if (typeof option == "string" || option instanceof URL || option instanceof URLSearchParams) { + requestParams.url = url(requestParams.url, option); + } else if (option && (option instanceof FormData || option instanceof ReadableStream || option instanceof Blob || option instanceof ArrayBuffer || option instanceof DataView)) { + requestParams.body = option; + } else if (option && typeof option == "object") { + Object.assign(requestParams, getRequestParams(option, requestParams)); + } + } + let body = requestParams.body; + if (body) { + 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); + } + } + let r = new Request(requestParams.url, requestParams); + Object.freeze(r); + return new Proxy(r, { + get(target, prop, receiver) { + switch (prop) { + case Symbol.metroSsource: + return target; + break; + case Symbol.metroProxy: + return true; + break; + case "with": + return function(...options2) { + if (body) { + options2.unshift({ body }); + } + return request(target, ...options2); + }; + break; + case "toString": + case "toJSON": + return function() { + return target[prop].apply(target); + }; + break; + case "blob": + case "text": + case "json": + return function() { + return target[prop].apply(target); + }; + break; + case "body": + if (!body) { + body = target.body; + } + if (body) { + if (body[Symbol.metroProxy]) { + return body; + } + return bodyProxy(body, target); + } + break; + } + if (target[prop] instanceof Function) { + return target[prop].bind(target); + } + return target[prop]; + } + }); + } + function getResponseParams(res, current) { + let params = current || {}; + if (!params.url && current.url) { + params.url = current.url; + } + for (let prop of ["status", "statusText", "headers", "body", "url", "type", "redirected"]) { + if (typeof res[prop] == "function") { + res[prop](params[prop], params); + } else if (typeof res[prop] != "undefined") { + if (prop == "url") { + params.url = new URL(res.url, params.url || "https://localhost/"); + } else { + params[prop] = res[prop]; + } + } + } + return params; + } + function response(...options) { + let responseParams = {}; + for (let option of options) { + if (typeof option == "string") { + responseParams.body = option; + } else if (option instanceof Response) { + Object.assign(responseParams, getResponseParams(option, responseParams)); + } else if (option && typeof option == "object") { + 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; + } else { + Object.assign(responseParams, getResponseParams(option, responseParams)); + } + } + } + let r = new Response(responseParams.body, responseParams); + Object.freeze(r); + return new Proxy(r, { + get(target, prop, receiver) { + switch (prop) { + case Symbol.metroProxy: + return true; + break; + case Symbol.metroSource: + return target; + break; + case "with": + return function(...options2) { + return response(target, ...options2); + }; + break; + case "body": + if (responseParams.body) { + if (responseParams.body[Symbol.metroProxy]) { + return responseParams.body; + } + return bodyProxy(responseParams.body, target); + } else { + return bodyProxy("", target); + } + break; + case "ok": + return target.status >= 200 && target.status < 400; + break; + case "headers": + return target.headers; + break; + default: + if (prop in responseParams && prop != "toString") { + return responseParams[prop]; + } + if (prop in target && prop != "toString") { + if (typeof target[prop] == "function") { + return function(...args) { + return target[prop].apply(target, args); + }; + } + return target[prop]; + } + break; + } + return void 0; + } + }); + } + function appendSearchParams(url2, params) { + if (typeof params == "function") { + params(url2.searchParams, url2); + } else { + params = new URLSearchParams(params); + params.forEach((value, key) => { + url2.searchParams.append(key, value); + }); + } + } + function url(...options) { + let validParams = [ + "hash", + "host", + "hostname", + "href", + "password", + "pathname", + "port", + "protocol", + "username", + "search", + "searchParams" + ]; + let u = new URL("https://localhost/"); + for (let option of options) { + if (typeof option == "string" || option instanceof String) { + u = new URL(option, u); + } else if (option instanceof URL || typeof Location != "undefined" && option instanceof Location) { + u = new URL(option); + } else if (option instanceof URLSearchParams) { + appendSearchParams(u, option); + } else if (option && typeof option == "object") { + for (let param in option) { + if (param == "search") { + if (typeof option.search == "function") { + option.search(u.search, u); + } else { + u.search = new URLSearchParams(option.search); + } + } else if (param == "searchParams") { + appendSearchParams(u, option.searchParams); + } else { + if (!validParams.includes(param)) { + throw metroError("metro.url: unknown url parameter " + metroURL + "url/unknown-param-name/", param); + } + if (typeof option[param] == "function") { + option[param](u[param], u); + } 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]; + } else if (typeof option[param] == "object" && option[param].toString) { + u[param] = option[param].toString(); + } else { + throw metroError("metro.url: unsupported value for " + param + " " + metroURL + "url/unsupported-param-value/", options[param]); + } + } + } + } else { + throw metroError("metro.url: unsupported option value " + metroURL + "url/unsupported-option-value/", option); + } + } + Object.freeze(u); + return new Proxy(u, { + get(target, prop, receiver) { + switch (prop) { + case Symbol.metroProxy: + return true; + break; + case Symbol.metroSource: + return target; + break; + case "with": + return function(...options2) { + return url(target, ...options2); + }; + break; + case "toString": + case "toJSON": + return function() { + return target[prop](); + }; + break; + } + return target[prop]; + } + }); + } + function formdata(...options) { + var params = new FormData(); + for (let option of options) { + if (option instanceof FormData) { + for (let entry of option.entries()) { + params.append(entry[0], entry[1]); + } + } else if (option && typeof option == "object") { + for (let entry of Object.entries(option)) { + if (Array.isArray(entry[1])) { + for (let value of entry[1]) { + params.append(entry[0], value); + } + } else { + params.append(entry[0], entry[1]); + } + } + } else { + throw new metroError("metro.formdata: unknown option type, only FormData or Object supported", option); + } + } + Object.freeze(params); + return new Proxy(params, { + get: (target, prop, receiver) => { + switch (prop) { + case Symbol.metroProxy: + return true; + break; + case Symbol.metroSource: + return target; + break; + case "with": + return function(...options2) { + return formdata(target, ...options2); + }; + break; + } + return target[prop]; + } + }); + } + var metroConsole = { + error: (message, ...details) => { + console.error("\u24C2\uFE0F ", message, ...details); + }, + info: (message, ...details) => { + console.info("\u24C2\uFE0F ", message, ...details); + }, + group: (name) => { + console.group("\u24C2\uFE0F " + name); + }, + groupEnd: (name) => { + console.groupEnd("\u24C2\uFE0F " + name); + } + }; + function metroError(message, ...details) { + metroConsole.error(message, ...details); + return new Error(message, ...details); + } + var trace = { + /** + * Adds a named tracer function + * @param {string} name - the name of the tracer + * @param {Function} tracer - the tracer function to call + */ + add(name, tracer) { + Client.tracers[name] = tracer; + }, + /** + * Removes a named tracer function + * @param {string} name + */ + delete(name) { + delete Client.tracers[name]; + }, + /** + * Removes all tracer functions + */ + clear() { + Client.tracers = {}; + }, + /** + * Returns a set of request and response tracer functions that use the + * console.group feature to shows nested request/response pairs, with + * most commonly needed information for debugging + */ + group() { + let group = 0; + return { + request: (req, middleware) => { + group++; + metroConsole.group(group); + metroConsole.info(req?.url, req, middleware); + }, + response: (res, middleware) => { + metroConsole.info(res?.body ? res.body[Symbol.metroSource] : null, res, middleware); + metroConsole.groupEnd(group); + group--; + } + }; + } + }; + + // src/mw/json.mjs + function jsonmw(options) { + options = Object.assign({ + reviver: null, + replacer: null, + space: "" + }, options); + return async (req, next) => { + if (["POST", "PUT", "PATCH", "QUERY"].includes(req.method)) { + req = req.with({ + headers: { + "Content-Type": "application/json", + "Accept": "application/json" + } + }); + if (req.body && typeof req.body[Symbol.metroSource] == "object") { + req = req.with({ + body: JSON.stringify(req.body[Symbol.metroSource], options.replacer, options.space) + }); + } + } else { + req = req.with({ + headers: { + "Accept": "application/json" + } + }); + } + let res = await next(req); + let body = await res.text(); + let json = JSON.parse(body, options.reviver); + return res.with({ + body: json + }); + }; + } + + // src/mw/thrower.mjs + function thrower(options) { + return async (req, next) => { + let res = await next(req); + if (!res.ok) { + if (options && typeof options[res.status] == "function") { + res = options[res.status].apply(res, req); + } else { + throw new Error(res.status + ": " + res.statusText, { + cause: res + }); + } + } + return res; + }; + } + + // src/everything.mjs + window.metro = Object.assign({}, metro_exports, { + mw: { + jsonmw, + thrower + } + }); +})(); //# sourceMappingURL=everything.js.map diff --git a/dist/everything.js.map b/dist/everything.js.map index f729b73..e613b65 100644 --- a/dist/everything.js.map +++ b/dist/everything.js.map @@ -1 +1,7 @@ -{"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 +{ + "version": 3, + "sources": ["../src/metro.mjs", "../src/mw/json.mjs", "../src/mw/thrower.mjs", "../src/everything.mjs"], + "sourcesContent": ["/**\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 */\nif (!Symbol.metroProxy) {\n\tSymbol.metroProxy = Symbol('isProxy')\n}\nif (!Symbol.metroSource) {\n\tSymbol.metroSource = 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[Symbol.metroProxy]) {\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\tif (req.body) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlet r = req.with()\n\t\t\t\t\t\tlet f = await r.formData()\n\t\t\t\t\t\tconsole.log('hier',f)\n\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t// ignore\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treq = req[Symbol.metroSource]\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 Symbol.metroProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase Symbol.metroSource:\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 (body && 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\tif (body && typeof body == 'object') {\n\t\t\t\treturn prop in body\n\t\t\t} else {\n\t\t\t\treturn prop in target\n\t\t\t}\n\t\t},\n\t\townKeys(target) {\n\t\t\tif (body && typeof body == 'object') {\n\t\t\t\treturn Reflect.ownKeys(body)\n\t\t\t} else {\n\t\t\t\treturn Reflect.ownKeys(target)\n\t\t\t}\n\t\t},\n\t\tgetOwnPropertyDescriptor(target, prop) {\n\t\t\tif (body && typeof body == 'object') {\n\t\t\t\treturn Object.getOwnPropertyDescriptor(body,prop)\n\t\t\t} else {\n\t\t\t\treturn Object.getOwnPropertyDescriptor(target,prop)\n\t\t\t}\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 Symbol.metroSsource:\n\t\t\t\t\treturn target\n\t\t\t\tbreak\n\t\t\t\tcase Symbol.metroProxy:\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[Symbol.metroProxy]) {\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\tif (target[prop] instanceof Function) {\n\t\t\t\treturn target[prop].bind(target)\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 Symbol.metroProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase Symbol.metroSource:\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[Symbol.metroProxy]) {\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 Symbol.metroProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase Symbol.metroSource:\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 Symbol.metroProxy:\n\t\t\t\t\treturn true\n\t\t\t\tbreak\n\t\t\t\tcase Symbol.metroSource:\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('\u24C2\uFE0F ',message, ...details)\n\t},\n\tinfo: (message, ...details) => {\n\t\tconsole.info('\u24C2\uFE0F ',message, ...details)\n\t},\n\tgroup: (name) => {\n\t\tconsole.group('\u24C2\uFE0F '+name)\n\t},\n\tgroupEnd: (name) => {\n\t\tconsole.groupEnd('\u24C2\uFE0F '+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[Symbol.metroSource]: 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\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[Symbol.metroSource] == 'object') {\n\t\t\t\treq = req.with({\n\t\t\t\t\tbody: JSON.stringify(req.body[Symbol.metroSource], 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}", "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})"], + "mappings": "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", + "names": ["options", "req", "next", "middleware", "options", "url"] +} diff --git a/package.json b/package.json index 5272dee..575e60b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@muze-nl/metro", - "version": "0.4.4", + "version": "0.5.0", "description": "http client with middleware support", "type": "module", "source": [ "src/browser.mjs", "src/everything.mjs" ], @@ -18,7 +18,8 @@ "scripts": { "test": "tap test/*.mjs", "tap": "tap", - "build": "parcel build" + "build-dev": "esbuild --bundle src/browser.mjs --outfile=dist/browser.js --sourcemap; esbuild --bundle src/everything.mjs --outfile=dist/everything.js --sourcemap", + "build": "esbuild --bundle src/browser.mjs --outfile=dist/browser.min.js --minify --sourcemap; esbuild --bundle src/everything.mjs --outfile=dist/everything.min.js --minify --sourcemap" }, "repository": { "type": "git", diff --git a/src/metro.mjs b/src/metro.mjs index 29c822d..d60a765 100644 --- a/src/metro.mjs +++ b/src/metro.mjs @@ -8,9 +8,11 @@ const metroURL = 'https://metro.muze.nl/details/' * - isProxy: used to test if an object is a metro Proxy to another object * - source: used to return the actual source (target) of a metro Proxy */ -export const symbols = { - isProxy: Symbol('isProxy'), - source: Symbol('source') +if (!Symbol.metroProxy) { + Symbol.metroProxy = Symbol('isProxy') +} +if (!Symbol.metroSource) { + Symbol.metroSource = Symbol('source') } /** @@ -122,11 +124,11 @@ class Client const metrofetch = async function browserFetch(req) { - if (req[symbols.isProxy]) { + if (req[Symbol.metroProxy]) { // even though a Proxy is supposed to be 'invisible' // fetch() doesn't work with the proxy (in Firefox), // you need the actual Request object here - req = req[symbols.source] + req = req[Symbol.metroSource] } const res = await fetch(req) return response(res) @@ -248,10 +250,10 @@ function bodyProxy(body, r) return new Proxy(source, { get(target, prop, receiver) { switch (prop) { - case symbols.isProxy: + case Symbol.metroProxy: return true break - case symbols.source: + case Symbol.metroSource: return body break case 'toString': @@ -260,7 +262,7 @@ function bodyProxy(body, r) } break } - if (typeof body == 'object') { + if (body && typeof body == 'object') { if (prop in body) { if (typeof body[prop] == 'function') { return function(...args) { @@ -282,13 +284,25 @@ function bodyProxy(body, r) } }, has(target, prop) { - return prop in body + if (body && typeof body == 'object') { + return prop in body + } else { + return prop in target + } }, ownKeys(target) { - return Reflect.ownKeys(body) + if (body && typeof body == 'object') { + return Reflect.ownKeys(body) + } else { + return Reflect.ownKeys(target) + } }, getOwnPropertyDescriptor(target, prop) { - return Object.getOwnPropertyDescriptor(body,prop) + if (body && typeof body == 'object') { + return Object.getOwnPropertyDescriptor(body,prop) + } else { + return Object.getOwnPropertyDescriptor(target,prop) + } } }) } @@ -384,10 +398,10 @@ export function request(...options) return new Proxy(r, { get(target, prop, receiver) { switch(prop) { - case symbols.source: + case Symbol.metroSsource: return target break - case symbols.isProxy: + case Symbol.metroProxy: return true break case 'with': @@ -423,13 +437,16 @@ export function request(...options) body = target.body } if (body) { - if (body[symbols.isProxy]) { + if (body[Symbol.metroProxy]) { return body } return bodyProxy(body, target) } break } + if (target[prop] instanceof Function) { + return target[prop].bind(target) + } return target[prop] } }) @@ -498,10 +515,10 @@ export function response(...options) return new Proxy(r, { get(target, prop, receiver) { switch(prop) { - case symbols.isProxy: + case Symbol.metroProxy: return true break - case symbols.source: + case Symbol.metroSource: return target break case 'with': @@ -511,7 +528,7 @@ export function response(...options) break case 'body': if (responseParams.body) { - if (responseParams.body[symbols.isProxy]) { + if (responseParams.body[Symbol.metroProxy]) { return responseParams.body } return bodyProxy(responseParams.body, target) @@ -621,10 +638,10 @@ export function url(...options) return new Proxy(u, { get(target, prop, receiver) { switch(prop) { - case symbols.isProxy: + case Symbol.metroProxy: return true break - case symbols.source: + case Symbol.metroSource: return target break case 'with': @@ -681,10 +698,10 @@ export function formdata(...options) return new Proxy(params, { get: (target,prop,receiver) => { switch(prop) { - case symbols.isProxy: + case Symbol.metroProxy: return true break - case symbols.source: + case Symbol.metroSource: return target break case 'with': @@ -768,7 +785,7 @@ export const trace = { metroConsole.info(req?.url, req, middleware) }, response: (res, middleware) => { - metroConsole.info(res?.body ? res.body[symbols.source]: null, res, middleware) + metroConsole.info(res?.body ? res.body[Symbol.metroSource]: null, res, middleware) metroConsole.groupEnd(group) group-- } diff --git a/src/mw/json.mjs b/src/mw/json.mjs index 9517da6..852a31f 100644 --- a/src/mw/json.mjs +++ b/src/mw/json.mjs @@ -15,9 +15,9 @@ export default function jsonmw(options) { 'Accept':'application/json' } }) - if (req.body && typeof req.body[metro.symbols.source] == 'object') { + if (req.body && typeof req.body[Symbol.metroSource] == 'object') { req = req.with({ - body: JSON.stringify(req.body[metro.symbols.source], options.replacer, options.space) + body: JSON.stringify(req.body[Symbol.metroSource], options.replacer, options.space) }) } } else {