From b0ac9abcc5d6a9d3f7bc7279847083c59fd65d47 Mon Sep 17 00:00:00 2001 From: Auke van Slooten Date: Fri, 31 Jan 2025 17:03:02 +0100 Subject: [PATCH] bumped version --- dist/browser.js | 3 +++ dist/browser.js.map | 4 ++-- dist/browser.min.js | 2 +- dist/browser.min.js.map | 4 ++-- dist/everything.js | 3 +++ dist/everything.js.map | 4 ++-- dist/everything.min.js | 2 +- dist/everything.min.js.map | 4 ++-- package.json | 2 +- 9 files changed, 17 insertions(+), 11 deletions(-) diff --git a/dist/browser.js b/dist/browser.js index 5d78e1b..1fce6c9 100644 --- a/dist/browser.js +++ b/dist/browser.js @@ -298,6 +298,9 @@ if (responseParams.body) { data = responseParams.body; } + if ([101, 204, 205, 304].includes(responseParams.status)) { + responseParams.body = null; + } let r = new Response(responseParams.body, responseParams); Object.freeze(r); return new Proxy(r, { diff --git a/dist/browser.js.map b/dist/browser.js.map index 6c078ca..13cf067 100644 --- a/dist/browser.js.map +++ b/dist/browser.js.map @@ -1,7 +1,7 @@ { "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 * @method fetch\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/', 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/fetch-missing-url/', 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|| options instanceof String) \n\t\t{\n\t\t\tthrow metroError('metro.client.fetch: Invalid options parameter '+metroURL+'client/fetch-invalid-options/', options)\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\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 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\tlet value = req[prop]\n\t\tif (typeof value=='undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = url(params.url, value)\n\t\t\t} else if (prop == 'headers') {\n\t\t\t\tparams.headers = new Headers(current.headers)\n\t\t\t\tif (!(value instanceof Headers)) {\n\t\t\t\t\tvalue = new Headers(req.headers)\n\t\t\t\t}\n\t\t\t\tfor (let [key, val] of value.entries()) {\n\t\t\t\t\tparams.headers.set(key, val)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (req instanceof Request && req.data) {\n\t\t// Request.body is always transformed into ReadableStreem\n\t\t// metro.request.data is the original body passed to Request()\n\t\tparams.body = req.data\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 r = new Request(requestParams.url, requestParams)\n\tlet data = requestParams.body\n\tif (data) {\n\t\tif (typeof data == 'object'\n\t\t\t&& !(data instanceof String)\n\t\t\t&& !(data instanceof ReadableStream)\n\t\t\t&& !(data instanceof Blob)\n\t\t\t&& !(data instanceof ArrayBuffer)\n\t\t\t&& !(data instanceof DataView)\n\t\t\t&& !(data instanceof FormData)\n\t\t\t&& !(data instanceof URLSearchParams)\n\t\t\t&& (typeof TypedArray=='undefined' || !(data instanceof TypedArray))\n\t\t) {\n\t\t\t// if we are here, body is set with an object of a type\n\t\t\t// not natively understood by Request, coerce it to a string\n\t\t\t// using toString({headers}) instead of just toString()\n\t\t\tif (typeof data.toString == 'function') {\n\t\t\t\trequestParams.body = data.toString({headers:r.headers})\n\t\t\t\tr = new Request(requestParams.url, requestParams)\n\t\t\t}\n\t\t}\n\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.metroSource:\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 (data) { // data is kept in a seperate value, if it set earlier\n\t\t\t\t\t\t\toptions.unshift({ body: data }) // 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 'data':\n\t\t\t\t\treturn data\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (target[prop] instanceof Function) {\n\t\t\t\tif (prop === 'clone') {\n\t\t\t\t\t// TODO: set req.data as the body of the clone\n\t\t\t\t}\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\tlet value = res[prop]\n\t\tif (typeof value == 'undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = new URL(value, params.url || 'https://localhost/')\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (res instanceof Response && res.data) {\n\t\t// Response.body is always transformed into ReadableStreem FIXME: check this\n\t\t// metro.response.data is the original body passed to Response()\n\t\tparams.body = res.data\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 data = undefined\n\tif (responseParams.body) {\n\t\tdata = responseParams.body\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 'data':\n\t\t\t\t\t// body is turned into ReadableStream\n\t\t\t\t\t// data is the original body param\n\t\t\t\t\treturn data\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}\n\t\t\tif (typeof target[prop] == '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 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\tswitch(param) {\n\t\t\t\t\tcase 'search':\n\t\t\t\t\t\tif (typeof option.search == 'function') {\n\t\t\t\t\t\t\toption.search(u.search, u)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tu.search = new URLSearchParams(option.search)\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t\tcase 'searchParams':\n\t\t\t\t\t\tappendSearchParams(u, option.searchParams)\n\t\t\t\t\tbreak\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (!validParams.includes(param)) {\n\t\t\t\t\t\t\tthrow metroError('metro.url: unknown url parameter '+metroURL+'url/unknown-param-name/', param)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (typeof option[param] == 'function') {\n\t\t\t\t\t\t\toption[param](u[param], u)\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\ttypeof option[param] == 'string' || option[param] instanceof String \n\t\t\t\t\t\t\t|| typeof option[param] == 'number' || option[param] instanceof Number\n\t\t\t\t\t\t\t|| typeof option[param] == 'boolean' || option[param] instanceof Boolean\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tu[param] = ''+option[param]\n\t\t\t\t\t\t} else if (typeof option[param] == 'object' && option[param].toString) {\n\t\t\t\t\t\t\tu[param] = option[param].toString()\n\t\t\t\t\t\t} else {\n\t\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\t}\n\t\t\t\t\tbreak\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 'filename':\n\t\t\t\t\treturn target.pathname.split('/').pop()\n\t\t\t\tbreak\n\t\t\t\tcase 'folderpath':\n\t\t\t\t\treturn target.pathname.substring(0,target.pathname.lastIndexOf('\\\\')+1)\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\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 HTMLFormElement) {\n\t\t\toption = new FormData(option)\n\t\t}\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 '+metroURL+'formdata/unknown-option-value/', 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\t//TODO: add toString() that can check\n\t\t\t\t//headers param: toString({headers:request.headers})\n\t\t\t\t//for the content-type\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}\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\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\nif (!globalThis.metro) {\n\tglobalThis.metro = metro\n}\n\nexport default metro"], - "mappings": "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", + "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 * @method fetch\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/', 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/fetch-missing-url/', 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|| options instanceof String) \n\t\t{\n\t\t\tthrow metroError('metro.client.fetch: Invalid options parameter '+metroURL+'client/fetch-invalid-options/', options)\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\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 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\tlet value = req[prop]\n\t\tif (typeof value=='undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = url(params.url, value)\n\t\t\t} else if (prop == 'headers') {\n\t\t\t\tparams.headers = new Headers(current.headers)\n\t\t\t\tif (!(value instanceof Headers)) {\n\t\t\t\t\tvalue = new Headers(req.headers)\n\t\t\t\t}\n\t\t\t\tfor (let [key, val] of value.entries()) {\n\t\t\t\t\tparams.headers.set(key, val)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (req instanceof Request && req.data) {\n\t\t// Request.body is always transformed into ReadableStreem\n\t\t// metro.request.data is the original body passed to Request()\n\t\tparams.body = req.data\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 r = new Request(requestParams.url, requestParams)\n\tlet data = requestParams.body\n\tif (data) {\n\t\tif (typeof data == 'object'\n\t\t\t&& !(data instanceof String)\n\t\t\t&& !(data instanceof ReadableStream)\n\t\t\t&& !(data instanceof Blob)\n\t\t\t&& !(data instanceof ArrayBuffer)\n\t\t\t&& !(data instanceof DataView)\n\t\t\t&& !(data instanceof FormData)\n\t\t\t&& !(data instanceof URLSearchParams)\n\t\t\t&& (typeof TypedArray=='undefined' || !(data instanceof TypedArray))\n\t\t) {\n\t\t\t// if we are here, body is set with an object of a type\n\t\t\t// not natively understood by Request, coerce it to a string\n\t\t\t// using toString({headers}) instead of just toString()\n\t\t\tif (typeof data.toString == 'function') {\n\t\t\t\trequestParams.body = data.toString({headers:r.headers})\n\t\t\t\tr = new Request(requestParams.url, requestParams)\n\t\t\t}\n\t\t}\n\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.metroSource:\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 (data) { // data is kept in a seperate value, if it set earlier\n\t\t\t\t\t\t\toptions.unshift({ body: data }) // 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 'data':\n\t\t\t\t\treturn data\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (target[prop] instanceof Function) {\n\t\t\t\tif (prop === 'clone') {\n\t\t\t\t\t// TODO: set req.data as the body of the clone\n\t\t\t\t}\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\tlet value = res[prop]\n\t\tif (typeof value == 'undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = new URL(value, params.url || 'https://localhost/')\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (res instanceof Response && res.data) {\n\t\t// Response.body is always transformed into ReadableStreem FIXME: check this\n\t\t// metro.response.data is the original body passed to Response()\n\t\tparams.body = res.data\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 data = undefined\n\tif (responseParams.body) {\n\t\tdata = responseParams.body\n\t}\n\t// if response status is 'null body status', don't set a body\n\t// that is response.status in [101, 204, 205, 304 ] \n\t// see: https://fetch.spec.whatwg.org/#statuses\n\tif ([101, 204, 205, 304 ].includes(responseParams.status)) {\n\t\tresponseParams.body = null\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 'data':\n\t\t\t\t\t// body is turned into ReadableStream\n\t\t\t\t\t// data is the original body param\n\t\t\t\t\treturn data\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}\n\t\t\tif (typeof target[prop] == '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 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\tswitch(param) {\n\t\t\t\t\tcase 'search':\n\t\t\t\t\t\tif (typeof option.search == 'function') {\n\t\t\t\t\t\t\toption.search(u.search, u)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tu.search = new URLSearchParams(option.search)\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t\tcase 'searchParams':\n\t\t\t\t\t\tappendSearchParams(u, option.searchParams)\n\t\t\t\t\tbreak\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (!validParams.includes(param)) {\n\t\t\t\t\t\t\tthrow metroError('metro.url: unknown url parameter '+metroURL+'url/unknown-param-name/', param)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (typeof option[param] == 'function') {\n\t\t\t\t\t\t\toption[param](u[param], u)\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\ttypeof option[param] == 'string' || option[param] instanceof String \n\t\t\t\t\t\t\t|| typeof option[param] == 'number' || option[param] instanceof Number\n\t\t\t\t\t\t\t|| typeof option[param] == 'boolean' || option[param] instanceof Boolean\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tu[param] = ''+option[param]\n\t\t\t\t\t\t} else if (typeof option[param] == 'object' && option[param].toString) {\n\t\t\t\t\t\t\tu[param] = option[param].toString()\n\t\t\t\t\t\t} else {\n\t\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\t}\n\t\t\t\t\tbreak\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 'filename':\n\t\t\t\t\treturn target.pathname.split('/').pop()\n\t\t\t\tbreak\n\t\t\t\tcase 'folderpath':\n\t\t\t\t\treturn target.pathname.substring(0,target.pathname.lastIndexOf('\\\\')+1)\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\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 HTMLFormElement) {\n\t\t\toption = new FormData(option)\n\t\t}\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 '+metroURL+'formdata/unknown-option-value/', 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\t//TODO: add toString() that can check\n\t\t\t\t//headers param: toString({headers:request.headers})\n\t\t\t\t//for the content-type\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}\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\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\nif (!globalThis.metro) {\n\tglobalThis.metro = metro\n}\n\nexport default metro"], + "mappings": "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", "names": ["options", "req", "next", "middleware", "options", "url"] } diff --git a/dist/browser.min.js b/dist/browser.min.js index 8b3d5f9..a22357a 100644 --- a/dist/browser.min.js +++ b/dist/browser.min.js @@ -1,2 +1,2 @@ -(()=>{var R=Object.defineProperty;var j=(n,o)=>{for(var e in o)R(n,e,{get:o[e],enumerable:!0})};var b={};j(b,{client:()=>L,formdata:()=>v,metroError:()=>f,request:()=>m,response:()=>w,trace:()=>A,url:()=>h});var l="https://metro.muze.nl/details/";Symbol.metroProxy||(Symbol.metroProxy=Symbol("isProxy"));Symbol.metroSource||(Symbol.metroSource=Symbol("source"));var u=class n{#e={url:typeof window<"u"?window.location:"https://localhost"};#t=["get","post","put","delete","patch","head","options","query"];static tracers={};constructor(...o){for(let e of o)if(typeof e=="string"||e instanceof String)this.#e.url=""+e;else if(e instanceof n)Object.assign(this.#e,e.#e);else if(e instanceof Function)this.#r([e]);else if(e&&typeof e=="object")for(let r in e)r=="middlewares"?this.#r(e[r]):typeof e[r]=="function"?this.#e[r]=e[r](this.#e[r],this.#e):this.#e[r]=e[r];this.#e.verbs&&(this.#t=this.#e.verbs,delete this.#e.verbs);for(let e of this.#t)this[e]=async function(...r){return this.fetch(m(this.#e,...r,{method:e.toUpperCase()}))};Object.freeze(this)}#r(o){typeof o=="function"&&(o=[o]);let e=o.findIndex(r=>typeof r!="function");if(e>=0)throw f("metro.client: middlewares must be a function or an array of functions "+l+"client/invalid-middlewares/",o[e]);Array.isArray(this.#e.middlewares)||(this.#e.middlewares=[]),this.#e.middlewares=this.#e.middlewares.concat(o)}fetch(o,e){if(o=m(o,e),!o.url)throw f("metro.client."+o.method.toLowerCase()+": Missing url parameter "+l+"client/fetch-missing-url/",o);if(e||(e={}),typeof e!="object"||e instanceof String)throw f("metro.client.fetch: Invalid options parameter "+l+"client/fetch-invalid-options/",e);let t=[async function(i){i[Symbol.metroProxy]&&(i=i[Symbol.metroSource]);let d=await fetch(i);return w(d)}].concat(this.#e?.middlewares?.slice()||[]);e=Object.assign({},this.#e,e);let a;for(let s of t)a=function(i,d){return async function(S){let p,P=Object.values(n.tracers);for(let c of P)c.request&&c.request.call(c,S,d);p=await d(S,i);for(let c of P)c.response&&c.response.call(c,p,d);return p}}(a,s);return a(o)}with(...o){return new n(this,...o)}};function L(...n){return new u(...n)}function g(n,o){let e=o||{};!e.url&&o.url&&(e.url=o.url);for(let r of["method","headers","body","mode","credentials","cache","redirect","referrer","referrerPolicy","integrity","keepalive","signal","priority","url"]){let t=n[r];if(!(typeof t>"u"||t==null))if(t?.[Symbol.metroProxy]&&(t=t[Symbol.metroSource]),typeof t=="function")e[r]=t(e[r],e);else if(r=="url")e.url=h(e.url,t);else if(r=="headers"){e.headers=new Headers(o.headers),t instanceof Headers||(t=new Headers(n.headers));for(let[a,s]of t.entries())e.headers.set(a,s)}else e[r]=t}return n instanceof Request&&n.data&&(e.body=n.data),e}function m(...n){let o={url:typeof window<"u"?window.location:"https://localhost/",duplex:"half"};for(let t of n)typeof t=="string"||t instanceof URL||t instanceof URLSearchParams?o.url=h(o.url,t):t&&(t instanceof FormData||t instanceof ReadableStream||t instanceof Blob||t instanceof ArrayBuffer||t instanceof DataView)?o.body=t:t&&typeof t=="object"&&Object.assign(o,g(t,o));let e=new Request(o.url,o),r=o.body;return r&&typeof r=="object"&&!(r instanceof String)&&!(r instanceof ReadableStream)&&!(r instanceof Blob)&&!(r instanceof ArrayBuffer)&&!(r instanceof DataView)&&!(r instanceof FormData)&&!(r instanceof URLSearchParams)&&(typeof TypedArray>"u"||!(r instanceof TypedArray))&&typeof r.toString=="function"&&(o.body=r.toString({headers:e.headers}),e=new Request(o.url,o)),Object.freeze(e),new Proxy(e,{get(t,a,s){switch(a){case Symbol.metroSource:return t;case Symbol.metroProxy:return!0;case"with":return function(...i){return r&&i.unshift({body:r}),m(t,...i)};case"data":return r}return t[a]instanceof Function?t[a].bind(t):t[a]}})}function x(n,o){let e=o||{};!e.url&&o.url&&(e.url=o.url);for(let r of["status","statusText","headers","body","url","type","redirected"]){let t=n[r];typeof t>"u"||t==null||(t?.[Symbol.metroProxy]&&(t=t[Symbol.metroSource]),typeof t=="function"?e[r]=t(e[r],e):r=="url"?e.url=new URL(t,e.url||"https://localhost/"):e[r]=t)}return n instanceof Response&&n.data&&(e.body=n.data),e}function w(...n){let o={};for(let t of n)typeof t=="string"?o.body=t:t instanceof Response?Object.assign(o,x(t,o)):t&&typeof t=="object"&&(t instanceof FormData||t instanceof Blob||t instanceof ArrayBuffer||t instanceof DataView||t instanceof ReadableStream||t instanceof URLSearchParams||t instanceof String||typeof TypedArray<"u"&&t instanceof TypedArray?o.body=t:Object.assign(o,x(t,o)));let e;o.body&&(e=o.body);let r=new Response(o.body,o);return Object.freeze(r),new Proxy(r,{get(t,a,s){switch(a){case Symbol.metroProxy:return!0;case Symbol.metroSource:return t;case"with":return function(...i){return w(t,...i)};case"data":return e;case"ok":return t.status>=200&&t.status<400}return typeof t[a]=="function"?t[a].bind(t):t[a]}})}function k(n,o){typeof o=="function"?o(n.searchParams,n):(o=new URLSearchParams(o),o.forEach((e,r)=>{n.searchParams.append(r,e)}))}function h(...n){let o=["hash","host","hostname","href","password","pathname","port","protocol","username","search","searchParams"],e=new URL("https://localhost/");for(let r of n)if(typeof r=="string"||r instanceof String)e=new URL(r,e);else if(r instanceof URL||typeof Location<"u"&&r instanceof Location)e=new URL(r);else if(r instanceof URLSearchParams)k(e,r);else if(r&&typeof r=="object")for(let t in r)switch(t){case"search":typeof r.search=="function"?r.search(e.search,e):e.search=new URLSearchParams(r.search);break;case"searchParams":k(e,r.searchParams);break;default:if(!o.includes(t))throw f("metro.url: unknown url parameter "+l+"url/unknown-param-name/",t);if(typeof r[t]=="function")r[t](e[t],e);else if(typeof r[t]=="string"||r[t]instanceof String||typeof r[t]=="number"||r[t]instanceof Number||typeof r[t]=="boolean"||r[t]instanceof Boolean)e[t]=""+r[t];else if(typeof r[t]=="object"&&r[t].toString)e[t]=r[t].toString();else throw f("metro.url: unsupported value for "+t+" "+l+"url/unsupported-param-value/",n[t]);break}else throw f("metro.url: unsupported option value "+l+"url/unsupported-option-value/",r);return Object.freeze(e),new Proxy(e,{get(r,t,a){switch(t){case Symbol.metroProxy:return!0;case Symbol.metroSource:return r;case"with":return function(...s){return h(r,...s)};case"filename":return r.pathname.split("/").pop();case"folderpath":return r.pathname.substring(0,r.pathname.lastIndexOf("\\")+1)}return r[t]instanceof Function?r[t].bind(r):r[t]}})}function v(...n){var o=new FormData;for(let e of n)if(e instanceof HTMLFormElement&&(e=new FormData(e)),e instanceof FormData)for(let r of e.entries())o.append(r[0],r[1]);else if(e&&typeof e=="object")for(let r of Object.entries(e))if(Array.isArray(r[1]))for(let t of r[1])o.append(r[0],t);else o.append(r[0],r[1]);else throw new f("metro.formdata: unknown option type "+l+"formdata/unknown-option-value/",e);return Object.freeze(o),new Proxy(o,{get:(e,r,t)=>{switch(r){case Symbol.metroProxy:return!0;case Symbol.metroSource:return e;case"with":return function(...a){return v(e,...a)}}return e[r]instanceof Function?e[r].bind(e):e[r]}})}var y={error:(n,...o)=>{console.error("\u24C2\uFE0F ",n,...o)},info:(n,...o)=>{console.info("\u24C2\uFE0F ",n,...o)},group:n=>{console.group("\u24C2\uFE0F "+n)},groupEnd:n=>{console.groupEnd("\u24C2\uFE0F "+n)}};function f(n,...o){return y.error(n,...o),new Error(n,...o)}var A={add(n,o){u.tracers[n]=o},delete(n){delete u.tracers[n]},clear(){u.tracers={}},group(){let n=0;return{request:(o,e)=>{n++,y.group(n),y.info(o?.url,o,e)},response:(o,e)=>{y.info(o?.body?o.body[Symbol.metroSource]:null,o,e),y.groupEnd(n),n--}}}};globalThis.metro||(globalThis.metro=b);var U=b;})(); +(()=>{var R=Object.defineProperty;var j=(n,o)=>{for(var e in o)R(n,e,{get:o[e],enumerable:!0})};var b={};j(b,{client:()=>L,formdata:()=>v,metroError:()=>f,request:()=>m,response:()=>w,trace:()=>A,url:()=>h});var l="https://metro.muze.nl/details/";Symbol.metroProxy||(Symbol.metroProxy=Symbol("isProxy"));Symbol.metroSource||(Symbol.metroSource=Symbol("source"));var u=class n{#e={url:typeof window<"u"?window.location:"https://localhost"};#t=["get","post","put","delete","patch","head","options","query"];static tracers={};constructor(...o){for(let e of o)if(typeof e=="string"||e instanceof String)this.#e.url=""+e;else if(e instanceof n)Object.assign(this.#e,e.#e);else if(e instanceof Function)this.#r([e]);else if(e&&typeof e=="object")for(let r in e)r=="middlewares"?this.#r(e[r]):typeof e[r]=="function"?this.#e[r]=e[r](this.#e[r],this.#e):this.#e[r]=e[r];this.#e.verbs&&(this.#t=this.#e.verbs,delete this.#e.verbs);for(let e of this.#t)this[e]=async function(...r){return this.fetch(m(this.#e,...r,{method:e.toUpperCase()}))};Object.freeze(this)}#r(o){typeof o=="function"&&(o=[o]);let e=o.findIndex(r=>typeof r!="function");if(e>=0)throw f("metro.client: middlewares must be a function or an array of functions "+l+"client/invalid-middlewares/",o[e]);Array.isArray(this.#e.middlewares)||(this.#e.middlewares=[]),this.#e.middlewares=this.#e.middlewares.concat(o)}fetch(o,e){if(o=m(o,e),!o.url)throw f("metro.client."+o.method.toLowerCase()+": Missing url parameter "+l+"client/fetch-missing-url/",o);if(e||(e={}),typeof e!="object"||e instanceof String)throw f("metro.client.fetch: Invalid options parameter "+l+"client/fetch-invalid-options/",e);let t=[async function(i){i[Symbol.metroProxy]&&(i=i[Symbol.metroSource]);let d=await fetch(i);return w(d)}].concat(this.#e?.middlewares?.slice()||[]);e=Object.assign({},this.#e,e);let a;for(let s of t)a=function(i,d){return async function(S){let p,P=Object.values(n.tracers);for(let c of P)c.request&&c.request.call(c,S,d);p=await d(S,i);for(let c of P)c.response&&c.response.call(c,p,d);return p}}(a,s);return a(o)}with(...o){return new n(this,...o)}};function L(...n){return new u(...n)}function g(n,o){let e=o||{};!e.url&&o.url&&(e.url=o.url);for(let r of["method","headers","body","mode","credentials","cache","redirect","referrer","referrerPolicy","integrity","keepalive","signal","priority","url"]){let t=n[r];if(!(typeof t>"u"||t==null))if(t?.[Symbol.metroProxy]&&(t=t[Symbol.metroSource]),typeof t=="function")e[r]=t(e[r],e);else if(r=="url")e.url=h(e.url,t);else if(r=="headers"){e.headers=new Headers(o.headers),t instanceof Headers||(t=new Headers(n.headers));for(let[a,s]of t.entries())e.headers.set(a,s)}else e[r]=t}return n instanceof Request&&n.data&&(e.body=n.data),e}function m(...n){let o={url:typeof window<"u"?window.location:"https://localhost/",duplex:"half"};for(let t of n)typeof t=="string"||t instanceof URL||t instanceof URLSearchParams?o.url=h(o.url,t):t&&(t instanceof FormData||t instanceof ReadableStream||t instanceof Blob||t instanceof ArrayBuffer||t instanceof DataView)?o.body=t:t&&typeof t=="object"&&Object.assign(o,g(t,o));let e=new Request(o.url,o),r=o.body;return r&&typeof r=="object"&&!(r instanceof String)&&!(r instanceof ReadableStream)&&!(r instanceof Blob)&&!(r instanceof ArrayBuffer)&&!(r instanceof DataView)&&!(r instanceof FormData)&&!(r instanceof URLSearchParams)&&(typeof TypedArray>"u"||!(r instanceof TypedArray))&&typeof r.toString=="function"&&(o.body=r.toString({headers:e.headers}),e=new Request(o.url,o)),Object.freeze(e),new Proxy(e,{get(t,a,s){switch(a){case Symbol.metroSource:return t;case Symbol.metroProxy:return!0;case"with":return function(...i){return r&&i.unshift({body:r}),m(t,...i)};case"data":return r}return t[a]instanceof Function?t[a].bind(t):t[a]}})}function x(n,o){let e=o||{};!e.url&&o.url&&(e.url=o.url);for(let r of["status","statusText","headers","body","url","type","redirected"]){let t=n[r];typeof t>"u"||t==null||(t?.[Symbol.metroProxy]&&(t=t[Symbol.metroSource]),typeof t=="function"?e[r]=t(e[r],e):r=="url"?e.url=new URL(t,e.url||"https://localhost/"):e[r]=t)}return n instanceof Response&&n.data&&(e.body=n.data),e}function w(...n){let o={};for(let t of n)typeof t=="string"?o.body=t:t instanceof Response?Object.assign(o,x(t,o)):t&&typeof t=="object"&&(t instanceof FormData||t instanceof Blob||t instanceof ArrayBuffer||t instanceof DataView||t instanceof ReadableStream||t instanceof URLSearchParams||t instanceof String||typeof TypedArray<"u"&&t instanceof TypedArray?o.body=t:Object.assign(o,x(t,o)));let e;o.body&&(e=o.body),[101,204,205,304].includes(o.status)&&(o.body=null);let r=new Response(o.body,o);return Object.freeze(r),new Proxy(r,{get(t,a,s){switch(a){case Symbol.metroProxy:return!0;case Symbol.metroSource:return t;case"with":return function(...i){return w(t,...i)};case"data":return e;case"ok":return t.status>=200&&t.status<400}return typeof t[a]=="function"?t[a].bind(t):t[a]}})}function k(n,o){typeof o=="function"?o(n.searchParams,n):(o=new URLSearchParams(o),o.forEach((e,r)=>{n.searchParams.append(r,e)}))}function h(...n){let o=["hash","host","hostname","href","password","pathname","port","protocol","username","search","searchParams"],e=new URL("https://localhost/");for(let r of n)if(typeof r=="string"||r instanceof String)e=new URL(r,e);else if(r instanceof URL||typeof Location<"u"&&r instanceof Location)e=new URL(r);else if(r instanceof URLSearchParams)k(e,r);else if(r&&typeof r=="object")for(let t in r)switch(t){case"search":typeof r.search=="function"?r.search(e.search,e):e.search=new URLSearchParams(r.search);break;case"searchParams":k(e,r.searchParams);break;default:if(!o.includes(t))throw f("metro.url: unknown url parameter "+l+"url/unknown-param-name/",t);if(typeof r[t]=="function")r[t](e[t],e);else if(typeof r[t]=="string"||r[t]instanceof String||typeof r[t]=="number"||r[t]instanceof Number||typeof r[t]=="boolean"||r[t]instanceof Boolean)e[t]=""+r[t];else if(typeof r[t]=="object"&&r[t].toString)e[t]=r[t].toString();else throw f("metro.url: unsupported value for "+t+" "+l+"url/unsupported-param-value/",n[t]);break}else throw f("metro.url: unsupported option value "+l+"url/unsupported-option-value/",r);return Object.freeze(e),new Proxy(e,{get(r,t,a){switch(t){case Symbol.metroProxy:return!0;case Symbol.metroSource:return r;case"with":return function(...s){return h(r,...s)};case"filename":return r.pathname.split("/").pop();case"folderpath":return r.pathname.substring(0,r.pathname.lastIndexOf("\\")+1)}return r[t]instanceof Function?r[t].bind(r):r[t]}})}function v(...n){var o=new FormData;for(let e of n)if(e instanceof HTMLFormElement&&(e=new FormData(e)),e instanceof FormData)for(let r of e.entries())o.append(r[0],r[1]);else if(e&&typeof e=="object")for(let r of Object.entries(e))if(Array.isArray(r[1]))for(let t of r[1])o.append(r[0],t);else o.append(r[0],r[1]);else throw new f("metro.formdata: unknown option type "+l+"formdata/unknown-option-value/",e);return Object.freeze(o),new Proxy(o,{get:(e,r,t)=>{switch(r){case Symbol.metroProxy:return!0;case Symbol.metroSource:return e;case"with":return function(...a){return v(e,...a)}}return e[r]instanceof Function?e[r].bind(e):e[r]}})}var y={error:(n,...o)=>{console.error("\u24C2\uFE0F ",n,...o)},info:(n,...o)=>{console.info("\u24C2\uFE0F ",n,...o)},group:n=>{console.group("\u24C2\uFE0F "+n)},groupEnd:n=>{console.groupEnd("\u24C2\uFE0F "+n)}};function f(n,...o){return y.error(n,...o),new Error(n,...o)}var A={add(n,o){u.tracers[n]=o},delete(n){delete u.tracers[n]},clear(){u.tracers={}},group(){let n=0;return{request:(o,e)=>{n++,y.group(n),y.info(o?.url,o,e)},response:(o,e)=>{y.info(o?.body?o.body[Symbol.metroSource]:null,o,e),y.groupEnd(n),n--}}}};globalThis.metro||(globalThis.metro=b);var U=b;})(); //# sourceMappingURL=browser.min.js.map diff --git a/dist/browser.min.js.map b/dist/browser.min.js.map index e41f392..f040aa4 100644 --- a/dist/browser.min.js.map +++ b/dist/browser.min.js.map @@ -1,7 +1,7 @@ { "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 * @method fetch\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/', 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/fetch-missing-url/', 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|| options instanceof String) \n\t\t{\n\t\t\tthrow metroError('metro.client.fetch: Invalid options parameter '+metroURL+'client/fetch-invalid-options/', options)\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\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 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\tlet value = req[prop]\n\t\tif (typeof value=='undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = url(params.url, value)\n\t\t\t} else if (prop == 'headers') {\n\t\t\t\tparams.headers = new Headers(current.headers)\n\t\t\t\tif (!(value instanceof Headers)) {\n\t\t\t\t\tvalue = new Headers(req.headers)\n\t\t\t\t}\n\t\t\t\tfor (let [key, val] of value.entries()) {\n\t\t\t\t\tparams.headers.set(key, val)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (req instanceof Request && req.data) {\n\t\t// Request.body is always transformed into ReadableStreem\n\t\t// metro.request.data is the original body passed to Request()\n\t\tparams.body = req.data\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 r = new Request(requestParams.url, requestParams)\n\tlet data = requestParams.body\n\tif (data) {\n\t\tif (typeof data == 'object'\n\t\t\t&& !(data instanceof String)\n\t\t\t&& !(data instanceof ReadableStream)\n\t\t\t&& !(data instanceof Blob)\n\t\t\t&& !(data instanceof ArrayBuffer)\n\t\t\t&& !(data instanceof DataView)\n\t\t\t&& !(data instanceof FormData)\n\t\t\t&& !(data instanceof URLSearchParams)\n\t\t\t&& (typeof TypedArray=='undefined' || !(data instanceof TypedArray))\n\t\t) {\n\t\t\t// if we are here, body is set with an object of a type\n\t\t\t// not natively understood by Request, coerce it to a string\n\t\t\t// using toString({headers}) instead of just toString()\n\t\t\tif (typeof data.toString == 'function') {\n\t\t\t\trequestParams.body = data.toString({headers:r.headers})\n\t\t\t\tr = new Request(requestParams.url, requestParams)\n\t\t\t}\n\t\t}\n\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.metroSource:\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 (data) { // data is kept in a seperate value, if it set earlier\n\t\t\t\t\t\t\toptions.unshift({ body: data }) // 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 'data':\n\t\t\t\t\treturn data\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (target[prop] instanceof Function) {\n\t\t\t\tif (prop === 'clone') {\n\t\t\t\t\t// TODO: set req.data as the body of the clone\n\t\t\t\t}\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\tlet value = res[prop]\n\t\tif (typeof value == 'undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = new URL(value, params.url || 'https://localhost/')\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (res instanceof Response && res.data) {\n\t\t// Response.body is always transformed into ReadableStreem FIXME: check this\n\t\t// metro.response.data is the original body passed to Response()\n\t\tparams.body = res.data\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 data = undefined\n\tif (responseParams.body) {\n\t\tdata = responseParams.body\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 'data':\n\t\t\t\t\t// body is turned into ReadableStream\n\t\t\t\t\t// data is the original body param\n\t\t\t\t\treturn data\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}\n\t\t\tif (typeof target[prop] == '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 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\tswitch(param) {\n\t\t\t\t\tcase 'search':\n\t\t\t\t\t\tif (typeof option.search == 'function') {\n\t\t\t\t\t\t\toption.search(u.search, u)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tu.search = new URLSearchParams(option.search)\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t\tcase 'searchParams':\n\t\t\t\t\t\tappendSearchParams(u, option.searchParams)\n\t\t\t\t\tbreak\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (!validParams.includes(param)) {\n\t\t\t\t\t\t\tthrow metroError('metro.url: unknown url parameter '+metroURL+'url/unknown-param-name/', param)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (typeof option[param] == 'function') {\n\t\t\t\t\t\t\toption[param](u[param], u)\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\ttypeof option[param] == 'string' || option[param] instanceof String \n\t\t\t\t\t\t\t|| typeof option[param] == 'number' || option[param] instanceof Number\n\t\t\t\t\t\t\t|| typeof option[param] == 'boolean' || option[param] instanceof Boolean\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tu[param] = ''+option[param]\n\t\t\t\t\t\t} else if (typeof option[param] == 'object' && option[param].toString) {\n\t\t\t\t\t\t\tu[param] = option[param].toString()\n\t\t\t\t\t\t} else {\n\t\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\t}\n\t\t\t\t\tbreak\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 'filename':\n\t\t\t\t\treturn target.pathname.split('/').pop()\n\t\t\t\tbreak\n\t\t\t\tcase 'folderpath':\n\t\t\t\t\treturn target.pathname.substring(0,target.pathname.lastIndexOf('\\\\')+1)\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\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 HTMLFormElement) {\n\t\t\toption = new FormData(option)\n\t\t}\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 '+metroURL+'formdata/unknown-option-value/', 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\t//TODO: add toString() that can check\n\t\t\t\t//headers param: toString({headers:request.headers})\n\t\t\t\t//for the content-type\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}\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\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\nif (!globalThis.metro) {\n\tglobalThis.metro = metro\n}\n\nexport default metro"], - "mappings": "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", + "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 * @method fetch\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/', 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/fetch-missing-url/', 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|| options instanceof String) \n\t\t{\n\t\t\tthrow metroError('metro.client.fetch: Invalid options parameter '+metroURL+'client/fetch-invalid-options/', options)\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\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 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\tlet value = req[prop]\n\t\tif (typeof value=='undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = url(params.url, value)\n\t\t\t} else if (prop == 'headers') {\n\t\t\t\tparams.headers = new Headers(current.headers)\n\t\t\t\tif (!(value instanceof Headers)) {\n\t\t\t\t\tvalue = new Headers(req.headers)\n\t\t\t\t}\n\t\t\t\tfor (let [key, val] of value.entries()) {\n\t\t\t\t\tparams.headers.set(key, val)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (req instanceof Request && req.data) {\n\t\t// Request.body is always transformed into ReadableStreem\n\t\t// metro.request.data is the original body passed to Request()\n\t\tparams.body = req.data\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 r = new Request(requestParams.url, requestParams)\n\tlet data = requestParams.body\n\tif (data) {\n\t\tif (typeof data == 'object'\n\t\t\t&& !(data instanceof String)\n\t\t\t&& !(data instanceof ReadableStream)\n\t\t\t&& !(data instanceof Blob)\n\t\t\t&& !(data instanceof ArrayBuffer)\n\t\t\t&& !(data instanceof DataView)\n\t\t\t&& !(data instanceof FormData)\n\t\t\t&& !(data instanceof URLSearchParams)\n\t\t\t&& (typeof TypedArray=='undefined' || !(data instanceof TypedArray))\n\t\t) {\n\t\t\t// if we are here, body is set with an object of a type\n\t\t\t// not natively understood by Request, coerce it to a string\n\t\t\t// using toString({headers}) instead of just toString()\n\t\t\tif (typeof data.toString == 'function') {\n\t\t\t\trequestParams.body = data.toString({headers:r.headers})\n\t\t\t\tr = new Request(requestParams.url, requestParams)\n\t\t\t}\n\t\t}\n\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.metroSource:\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 (data) { // data is kept in a seperate value, if it set earlier\n\t\t\t\t\t\t\toptions.unshift({ body: data }) // 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 'data':\n\t\t\t\t\treturn data\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (target[prop] instanceof Function) {\n\t\t\t\tif (prop === 'clone') {\n\t\t\t\t\t// TODO: set req.data as the body of the clone\n\t\t\t\t}\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\tlet value = res[prop]\n\t\tif (typeof value == 'undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = new URL(value, params.url || 'https://localhost/')\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (res instanceof Response && res.data) {\n\t\t// Response.body is always transformed into ReadableStreem FIXME: check this\n\t\t// metro.response.data is the original body passed to Response()\n\t\tparams.body = res.data\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 data = undefined\n\tif (responseParams.body) {\n\t\tdata = responseParams.body\n\t}\n\t// if response status is 'null body status', don't set a body\n\t// that is response.status in [101, 204, 205, 304 ] \n\t// see: https://fetch.spec.whatwg.org/#statuses\n\tif ([101, 204, 205, 304 ].includes(responseParams.status)) {\n\t\tresponseParams.body = null\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 'data':\n\t\t\t\t\t// body is turned into ReadableStream\n\t\t\t\t\t// data is the original body param\n\t\t\t\t\treturn data\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}\n\t\t\tif (typeof target[prop] == '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 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\tswitch(param) {\n\t\t\t\t\tcase 'search':\n\t\t\t\t\t\tif (typeof option.search == 'function') {\n\t\t\t\t\t\t\toption.search(u.search, u)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tu.search = new URLSearchParams(option.search)\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t\tcase 'searchParams':\n\t\t\t\t\t\tappendSearchParams(u, option.searchParams)\n\t\t\t\t\tbreak\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (!validParams.includes(param)) {\n\t\t\t\t\t\t\tthrow metroError('metro.url: unknown url parameter '+metroURL+'url/unknown-param-name/', param)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (typeof option[param] == 'function') {\n\t\t\t\t\t\t\toption[param](u[param], u)\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\ttypeof option[param] == 'string' || option[param] instanceof String \n\t\t\t\t\t\t\t|| typeof option[param] == 'number' || option[param] instanceof Number\n\t\t\t\t\t\t\t|| typeof option[param] == 'boolean' || option[param] instanceof Boolean\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tu[param] = ''+option[param]\n\t\t\t\t\t\t} else if (typeof option[param] == 'object' && option[param].toString) {\n\t\t\t\t\t\t\tu[param] = option[param].toString()\n\t\t\t\t\t\t} else {\n\t\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\t}\n\t\t\t\t\tbreak\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 'filename':\n\t\t\t\t\treturn target.pathname.split('/').pop()\n\t\t\t\tbreak\n\t\t\t\tcase 'folderpath':\n\t\t\t\t\treturn target.pathname.substring(0,target.pathname.lastIndexOf('\\\\')+1)\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\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 HTMLFormElement) {\n\t\t\toption = new FormData(option)\n\t\t}\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 '+metroURL+'formdata/unknown-option-value/', 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\t//TODO: add toString() that can check\n\t\t\t\t//headers param: toString({headers:request.headers})\n\t\t\t\t//for the content-type\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}\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\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\nif (!globalThis.metro) {\n\tglobalThis.metro = metro\n}\n\nexport default metro"], + "mappings": "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", "names": ["metro_exports", "__export", "client", "formdata", "metroError", "request", "response", "trace", "url", "metroURL", "Client", "_Client", "#options", "#verbs", "options", "option", "#addMiddlewares", "param", "verb", "middlewares", "index", "m", "req", "res", "next", "middleware", "tracers", "tracer", "getRequestParams", "req", "current", "params", "prop", "value", "url", "key", "val", "request", "options", "requestParams", "option", "r", "data", "target", "receiver", "getResponseParams", "res", "response", "responseParams", "appendSearchParams", "validParams", "u", "param", "metroError", "metroURL", "formdata", "entry", "metroConsole", "message", "details", "name", "trace", "tracer", "Client", "group", "middleware", "metro_exports", "browser_default"] } diff --git a/dist/everything.js b/dist/everything.js index 25a398d..096fd81 100644 --- a/dist/everything.js +++ b/dist/everything.js @@ -298,6 +298,9 @@ if (responseParams.body) { data = responseParams.body; } + if ([101, 204, 205, 304].includes(responseParams.status)) { + responseParams.body = null; + } let r = new Response(responseParams.body, responseParams); Object.freeze(r); return new Proxy(r, { diff --git a/dist/everything.js.map b/dist/everything.js.map index ecf2d5a..6547444 100644 --- a/dist/everything.js.map +++ b/dist/everything.js.map @@ -1,7 +1,7 @@ { "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 * @method fetch\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/', 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/fetch-missing-url/', 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|| options instanceof String) \n\t\t{\n\t\t\tthrow metroError('metro.client.fetch: Invalid options parameter '+metroURL+'client/fetch-invalid-options/', options)\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\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 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\tlet value = req[prop]\n\t\tif (typeof value=='undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = url(params.url, value)\n\t\t\t} else if (prop == 'headers') {\n\t\t\t\tparams.headers = new Headers(current.headers)\n\t\t\t\tif (!(value instanceof Headers)) {\n\t\t\t\t\tvalue = new Headers(req.headers)\n\t\t\t\t}\n\t\t\t\tfor (let [key, val] of value.entries()) {\n\t\t\t\t\tparams.headers.set(key, val)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (req instanceof Request && req.data) {\n\t\t// Request.body is always transformed into ReadableStreem\n\t\t// metro.request.data is the original body passed to Request()\n\t\tparams.body = req.data\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 r = new Request(requestParams.url, requestParams)\n\tlet data = requestParams.body\n\tif (data) {\n\t\tif (typeof data == 'object'\n\t\t\t&& !(data instanceof String)\n\t\t\t&& !(data instanceof ReadableStream)\n\t\t\t&& !(data instanceof Blob)\n\t\t\t&& !(data instanceof ArrayBuffer)\n\t\t\t&& !(data instanceof DataView)\n\t\t\t&& !(data instanceof FormData)\n\t\t\t&& !(data instanceof URLSearchParams)\n\t\t\t&& (typeof TypedArray=='undefined' || !(data instanceof TypedArray))\n\t\t) {\n\t\t\t// if we are here, body is set with an object of a type\n\t\t\t// not natively understood by Request, coerce it to a string\n\t\t\t// using toString({headers}) instead of just toString()\n\t\t\tif (typeof data.toString == 'function') {\n\t\t\t\trequestParams.body = data.toString({headers:r.headers})\n\t\t\t\tr = new Request(requestParams.url, requestParams)\n\t\t\t}\n\t\t}\n\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.metroSource:\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 (data) { // data is kept in a seperate value, if it set earlier\n\t\t\t\t\t\t\toptions.unshift({ body: data }) // 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 'data':\n\t\t\t\t\treturn data\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (target[prop] instanceof Function) {\n\t\t\t\tif (prop === 'clone') {\n\t\t\t\t\t// TODO: set req.data as the body of the clone\n\t\t\t\t}\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\tlet value = res[prop]\n\t\tif (typeof value == 'undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = new URL(value, params.url || 'https://localhost/')\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (res instanceof Response && res.data) {\n\t\t// Response.body is always transformed into ReadableStreem FIXME: check this\n\t\t// metro.response.data is the original body passed to Response()\n\t\tparams.body = res.data\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 data = undefined\n\tif (responseParams.body) {\n\t\tdata = responseParams.body\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 'data':\n\t\t\t\t\t// body is turned into ReadableStream\n\t\t\t\t\t// data is the original body param\n\t\t\t\t\treturn data\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}\n\t\t\tif (typeof target[prop] == '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 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\tswitch(param) {\n\t\t\t\t\tcase 'search':\n\t\t\t\t\t\tif (typeof option.search == 'function') {\n\t\t\t\t\t\t\toption.search(u.search, u)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tu.search = new URLSearchParams(option.search)\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t\tcase 'searchParams':\n\t\t\t\t\t\tappendSearchParams(u, option.searchParams)\n\t\t\t\t\tbreak\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (!validParams.includes(param)) {\n\t\t\t\t\t\t\tthrow metroError('metro.url: unknown url parameter '+metroURL+'url/unknown-param-name/', param)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (typeof option[param] == 'function') {\n\t\t\t\t\t\t\toption[param](u[param], u)\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\ttypeof option[param] == 'string' || option[param] instanceof String \n\t\t\t\t\t\t\t|| typeof option[param] == 'number' || option[param] instanceof Number\n\t\t\t\t\t\t\t|| typeof option[param] == 'boolean' || option[param] instanceof Boolean\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tu[param] = ''+option[param]\n\t\t\t\t\t\t} else if (typeof option[param] == 'object' && option[param].toString) {\n\t\t\t\t\t\t\tu[param] = option[param].toString()\n\t\t\t\t\t\t} else {\n\t\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\t}\n\t\t\t\t\tbreak\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 'filename':\n\t\t\t\t\treturn target.pathname.split('/').pop()\n\t\t\t\tbreak\n\t\t\t\tcase 'folderpath':\n\t\t\t\t\treturn target.pathname.substring(0,target.pathname.lastIndexOf('\\\\')+1)\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\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 HTMLFormElement) {\n\t\t\toption = new FormData(option)\n\t\t}\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 '+metroURL+'formdata/unknown-option-value/', 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\t//TODO: add toString() that can check\n\t\t\t\t//headers param: toString({headers:request.headers})\n\t\t\t\t//for the content-type\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}\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\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\tmimetype: 'application/json',\n\t\treviver: null,\n\t\treplacer: null,\n\t\tspace: ''\n\t}, options)\n\n\treturn async (req, next) => {\n\t\tif (!isJSON(req.headers.get('Accept'))) {\n\t\t\treq = req.with({\n\t\t\t\theaders: {\n\t 'Accept': options.mimetype\n\t }\n\t })\n\t\t}\n\t\tif (['POST','PUT','PATCH','QUERY'].includes(req.method)) {\n\t\t\tif (req.data && typeof req.data=='object' && !(req.data instanceof ReadableStream)) {\n\t\t\t\tif (!isJSON(req.headers.get('content-type'))) {\n\t\t\t\t\treq = req.with({\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t'Content-Type':options.mimetype,\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treq = req.with({\n\t\t\t\t\tbody: JSON.stringify(req.data, options.replacer, options.space)\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tlet res = await next(req)\n\t\tif (isJSON(res.headers.get('content-type'))) {\n\t\t\tlet tempRes = res.clone()\n\t\t\tlet body = await tempRes.text()\n\t\t\ttry {\n\t\t\t\tlet json = JSON.parse(body, options.reviver)\n\t\t\t\treturn res.with({\n\t\t\t\t\tbody: json\n\t\t\t\t})\n\t\t\t} catch(e) {\n\t\t\t\t// ignore parse errors\n\t\t\t}\n\t\t} \n\t\treturn res\n\t}\n}\n\nconst jsonRE = /^application\\/([a-zA-Z0-9\\-_]+\\+)?json\\b/\nfunction isJSON(contentType) {\n\treturn jsonRE.exec(contentType)\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 m from './metro.mjs'\nimport jsonmw from './mw/json.mjs'\nimport thrower from './mw/thrower.mjs'\n\nconst metro = Object.assign({}, m, {\n\tmw: {\n\t\tjsonmw,\n\t\tthrower\n\t}\n})\n\nif (!globalThis.metro) {\n\tglobalThis.metro = metro\n}\n\nexport default metro"], - "mappings": "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", + "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 * @method fetch\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/', 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/fetch-missing-url/', 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|| options instanceof String) \n\t\t{\n\t\t\tthrow metroError('metro.client.fetch: Invalid options parameter '+metroURL+'client/fetch-invalid-options/', options)\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\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 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\tlet value = req[prop]\n\t\tif (typeof value=='undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = url(params.url, value)\n\t\t\t} else if (prop == 'headers') {\n\t\t\t\tparams.headers = new Headers(current.headers)\n\t\t\t\tif (!(value instanceof Headers)) {\n\t\t\t\t\tvalue = new Headers(req.headers)\n\t\t\t\t}\n\t\t\t\tfor (let [key, val] of value.entries()) {\n\t\t\t\t\tparams.headers.set(key, val)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (req instanceof Request && req.data) {\n\t\t// Request.body is always transformed into ReadableStreem\n\t\t// metro.request.data is the original body passed to Request()\n\t\tparams.body = req.data\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 r = new Request(requestParams.url, requestParams)\n\tlet data = requestParams.body\n\tif (data) {\n\t\tif (typeof data == 'object'\n\t\t\t&& !(data instanceof String)\n\t\t\t&& !(data instanceof ReadableStream)\n\t\t\t&& !(data instanceof Blob)\n\t\t\t&& !(data instanceof ArrayBuffer)\n\t\t\t&& !(data instanceof DataView)\n\t\t\t&& !(data instanceof FormData)\n\t\t\t&& !(data instanceof URLSearchParams)\n\t\t\t&& (typeof TypedArray=='undefined' || !(data instanceof TypedArray))\n\t\t) {\n\t\t\t// if we are here, body is set with an object of a type\n\t\t\t// not natively understood by Request, coerce it to a string\n\t\t\t// using toString({headers}) instead of just toString()\n\t\t\tif (typeof data.toString == 'function') {\n\t\t\t\trequestParams.body = data.toString({headers:r.headers})\n\t\t\t\tr = new Request(requestParams.url, requestParams)\n\t\t\t}\n\t\t}\n\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.metroSource:\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 (data) { // data is kept in a seperate value, if it set earlier\n\t\t\t\t\t\t\toptions.unshift({ body: data }) // 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 'data':\n\t\t\t\t\treturn data\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (target[prop] instanceof Function) {\n\t\t\t\tif (prop === 'clone') {\n\t\t\t\t\t// TODO: set req.data as the body of the clone\n\t\t\t\t}\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\tlet value = res[prop]\n\t\tif (typeof value == 'undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = new URL(value, params.url || 'https://localhost/')\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (res instanceof Response && res.data) {\n\t\t// Response.body is always transformed into ReadableStreem FIXME: check this\n\t\t// metro.response.data is the original body passed to Response()\n\t\tparams.body = res.data\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 data = undefined\n\tif (responseParams.body) {\n\t\tdata = responseParams.body\n\t}\n\t// if response status is 'null body status', don't set a body\n\t// that is response.status in [101, 204, 205, 304 ] \n\t// see: https://fetch.spec.whatwg.org/#statuses\n\tif ([101, 204, 205, 304 ].includes(responseParams.status)) {\n\t\tresponseParams.body = null\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 'data':\n\t\t\t\t\t// body is turned into ReadableStream\n\t\t\t\t\t// data is the original body param\n\t\t\t\t\treturn data\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}\n\t\t\tif (typeof target[prop] == '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 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\tswitch(param) {\n\t\t\t\t\tcase 'search':\n\t\t\t\t\t\tif (typeof option.search == 'function') {\n\t\t\t\t\t\t\toption.search(u.search, u)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tu.search = new URLSearchParams(option.search)\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t\tcase 'searchParams':\n\t\t\t\t\t\tappendSearchParams(u, option.searchParams)\n\t\t\t\t\tbreak\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (!validParams.includes(param)) {\n\t\t\t\t\t\t\tthrow metroError('metro.url: unknown url parameter '+metroURL+'url/unknown-param-name/', param)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (typeof option[param] == 'function') {\n\t\t\t\t\t\t\toption[param](u[param], u)\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\ttypeof option[param] == 'string' || option[param] instanceof String \n\t\t\t\t\t\t\t|| typeof option[param] == 'number' || option[param] instanceof Number\n\t\t\t\t\t\t\t|| typeof option[param] == 'boolean' || option[param] instanceof Boolean\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tu[param] = ''+option[param]\n\t\t\t\t\t\t} else if (typeof option[param] == 'object' && option[param].toString) {\n\t\t\t\t\t\t\tu[param] = option[param].toString()\n\t\t\t\t\t\t} else {\n\t\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\t}\n\t\t\t\t\tbreak\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 'filename':\n\t\t\t\t\treturn target.pathname.split('/').pop()\n\t\t\t\tbreak\n\t\t\t\tcase 'folderpath':\n\t\t\t\t\treturn target.pathname.substring(0,target.pathname.lastIndexOf('\\\\')+1)\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\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 HTMLFormElement) {\n\t\t\toption = new FormData(option)\n\t\t}\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 '+metroURL+'formdata/unknown-option-value/', 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\t//TODO: add toString() that can check\n\t\t\t\t//headers param: toString({headers:request.headers})\n\t\t\t\t//for the content-type\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}\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\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\tmimetype: 'application/json',\n\t\treviver: null,\n\t\treplacer: null,\n\t\tspace: ''\n\t}, options)\n\n\treturn async (req, next) => {\n\t\tif (!isJSON(req.headers.get('Accept'))) {\n\t\t\treq = req.with({\n\t\t\t\theaders: {\n\t 'Accept': options.mimetype\n\t }\n\t })\n\t\t}\n\t\tif (['POST','PUT','PATCH','QUERY'].includes(req.method)) {\n\t\t\tif (req.data && typeof req.data=='object' && !(req.data instanceof ReadableStream)) {\n\t\t\t\tif (!isJSON(req.headers.get('content-type'))) {\n\t\t\t\t\treq = req.with({\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t'Content-Type':options.mimetype,\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treq = req.with({\n\t\t\t\t\tbody: JSON.stringify(req.data, options.replacer, options.space)\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tlet res = await next(req)\n\t\tif (isJSON(res.headers.get('content-type'))) {\n\t\t\tlet tempRes = res.clone()\n\t\t\tlet body = await tempRes.text()\n\t\t\ttry {\n\t\t\t\tlet json = JSON.parse(body, options.reviver)\n\t\t\t\treturn res.with({\n\t\t\t\t\tbody: json\n\t\t\t\t})\n\t\t\t} catch(e) {\n\t\t\t\t// ignore parse errors\n\t\t\t}\n\t\t} \n\t\treturn res\n\t}\n}\n\nconst jsonRE = /^application\\/([a-zA-Z0-9\\-_]+\\+)?json\\b/\nfunction isJSON(contentType) {\n\treturn jsonRE.exec(contentType)\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 m from './metro.mjs'\nimport jsonmw from './mw/json.mjs'\nimport thrower from './mw/thrower.mjs'\n\nconst metro = Object.assign({}, m, {\n\tmw: {\n\t\tjsonmw,\n\t\tthrower\n\t}\n})\n\nif (!globalThis.metro) {\n\tglobalThis.metro = metro\n}\n\nexport default metro"], + "mappings": "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", "names": ["options", "req", "next", "middleware", "options", "url"] } diff --git a/dist/everything.min.js b/dist/everything.min.js index 798d876..c41fc5b 100644 --- a/dist/everything.min.js +++ b/dist/everything.min.js @@ -1,2 +1,2 @@ -(()=>{var A=Object.defineProperty;var L=(n,o)=>{for(var t in o)A(n,t,{get:o[t],enumerable:!0})};var w={};L(w,{client:()=>U,formdata:()=>g,metroError:()=>f,request:()=>y,response:()=>b,trace:()=>T,url:()=>h});var l="https://metro.muze.nl/details/";Symbol.metroProxy||(Symbol.metroProxy=Symbol("isProxy"));Symbol.metroSource||(Symbol.metroSource=Symbol("source"));var u=class n{#e={url:typeof window<"u"?window.location:"https://localhost"};#t=["get","post","put","delete","patch","head","options","query"];static tracers={};constructor(...o){for(let t of o)if(typeof t=="string"||t instanceof String)this.#e.url=""+t;else if(t instanceof n)Object.assign(this.#e,t.#e);else if(t instanceof Function)this.#r([t]);else if(t&&typeof t=="object")for(let e in t)e=="middlewares"?this.#r(t[e]):typeof t[e]=="function"?this.#e[e]=t[e](this.#e[e],this.#e):this.#e[e]=t[e];this.#e.verbs&&(this.#t=this.#e.verbs,delete this.#e.verbs);for(let t of this.#t)this[t]=async function(...e){return this.fetch(y(this.#e,...e,{method:t.toUpperCase()}))};Object.freeze(this)}#r(o){typeof o=="function"&&(o=[o]);let t=o.findIndex(e=>typeof e!="function");if(t>=0)throw f("metro.client: middlewares must be a function or an array of functions "+l+"client/invalid-middlewares/",o[t]);Array.isArray(this.#e.middlewares)||(this.#e.middlewares=[]),this.#e.middlewares=this.#e.middlewares.concat(o)}fetch(o,t){if(o=y(o,t),!o.url)throw f("metro.client."+o.method.toLowerCase()+": Missing url parameter "+l+"client/fetch-missing-url/",o);if(t||(t={}),typeof t!="object"||t instanceof String)throw f("metro.client.fetch: Invalid options parameter "+l+"client/fetch-invalid-options/",t);let r=[async function(s){s[Symbol.metroProxy]&&(s=s[Symbol.metroSource]);let m=await fetch(s);return b(m)}].concat(this.#e?.middlewares?.slice()||[]);t=Object.assign({},this.#e,t);let a;for(let i of r)a=function(s,m){return async function(j){let p,v=Object.values(n.tracers);for(let c of v)c.request&&c.request.call(c,j,m);p=await m(j,s);for(let c of v)c.response&&c.response.call(c,p,m);return p}}(a,i);return a(o)}with(...o){return new n(this,...o)}};function U(...n){return new u(...n)}function E(n,o){let t=o||{};!t.url&&o.url&&(t.url=o.url);for(let e of["method","headers","body","mode","credentials","cache","redirect","referrer","referrerPolicy","integrity","keepalive","signal","priority","url"]){let r=n[e];if(!(typeof r>"u"||r==null))if(r?.[Symbol.metroProxy]&&(r=r[Symbol.metroSource]),typeof r=="function")t[e]=r(t[e],t);else if(e=="url")t.url=h(t.url,r);else if(e=="headers"){t.headers=new Headers(o.headers),r instanceof Headers||(r=new Headers(n.headers));for(let[a,i]of r.entries())t.headers.set(a,i)}else t[e]=r}return n instanceof Request&&n.data&&(t.body=n.data),t}function y(...n){let o={url:typeof window<"u"?window.location:"https://localhost/",duplex:"half"};for(let r of n)typeof r=="string"||r instanceof URL||r instanceof URLSearchParams?o.url=h(o.url,r):r&&(r instanceof FormData||r instanceof ReadableStream||r instanceof Blob||r instanceof ArrayBuffer||r instanceof DataView)?o.body=r:r&&typeof r=="object"&&Object.assign(o,E(r,o));let t=new Request(o.url,o),e=o.body;return e&&typeof e=="object"&&!(e instanceof String)&&!(e instanceof ReadableStream)&&!(e instanceof Blob)&&!(e instanceof ArrayBuffer)&&!(e instanceof DataView)&&!(e instanceof FormData)&&!(e instanceof URLSearchParams)&&(typeof TypedArray>"u"||!(e instanceof TypedArray))&&typeof e.toString=="function"&&(o.body=e.toString({headers:t.headers}),t=new Request(o.url,o)),Object.freeze(t),new Proxy(t,{get(r,a,i){switch(a){case Symbol.metroSource:return r;case Symbol.metroProxy:return!0;case"with":return function(...s){return e&&s.unshift({body:e}),y(r,...s)};case"data":return e}return r[a]instanceof Function?r[a].bind(r):r[a]}})}function R(n,o){let t=o||{};!t.url&&o.url&&(t.url=o.url);for(let e of["status","statusText","headers","body","url","type","redirected"]){let r=n[e];typeof r>"u"||r==null||(r?.[Symbol.metroProxy]&&(r=r[Symbol.metroSource]),typeof r=="function"?t[e]=r(t[e],t):e=="url"?t.url=new URL(r,t.url||"https://localhost/"):t[e]=r)}return n instanceof Response&&n.data&&(t.body=n.data),t}function b(...n){let o={};for(let r of n)typeof r=="string"?o.body=r:r instanceof Response?Object.assign(o,R(r,o)):r&&typeof r=="object"&&(r instanceof FormData||r instanceof Blob||r instanceof ArrayBuffer||r instanceof DataView||r instanceof ReadableStream||r instanceof URLSearchParams||r instanceof String||typeof TypedArray<"u"&&r instanceof TypedArray?o.body=r:Object.assign(o,R(r,o)));let t;o.body&&(t=o.body);let e=new Response(o.body,o);return Object.freeze(e),new Proxy(e,{get(r,a,i){switch(a){case Symbol.metroProxy:return!0;case Symbol.metroSource:return r;case"with":return function(...s){return b(r,...s)};case"data":return t;case"ok":return r.status>=200&&r.status<400}return typeof r[a]=="function"?r[a].bind(r):r[a]}})}function k(n,o){typeof o=="function"?o(n.searchParams,n):(o=new URLSearchParams(o),o.forEach((t,e)=>{n.searchParams.append(e,t)}))}function h(...n){let o=["hash","host","hostname","href","password","pathname","port","protocol","username","search","searchParams"],t=new URL("https://localhost/");for(let e of n)if(typeof e=="string"||e instanceof String)t=new URL(e,t);else if(e instanceof URL||typeof Location<"u"&&e instanceof Location)t=new URL(e);else if(e instanceof URLSearchParams)k(t,e);else if(e&&typeof e=="object")for(let r in e)switch(r){case"search":typeof e.search=="function"?e.search(t.search,t):t.search=new URLSearchParams(e.search);break;case"searchParams":k(t,e.searchParams);break;default:if(!o.includes(r))throw f("metro.url: unknown url parameter "+l+"url/unknown-param-name/",r);if(typeof e[r]=="function")e[r](t[r],t);else if(typeof e[r]=="string"||e[r]instanceof String||typeof e[r]=="number"||e[r]instanceof Number||typeof e[r]=="boolean"||e[r]instanceof Boolean)t[r]=""+e[r];else if(typeof e[r]=="object"&&e[r].toString)t[r]=e[r].toString();else throw f("metro.url: unsupported value for "+r+" "+l+"url/unsupported-param-value/",n[r]);break}else throw f("metro.url: unsupported option value "+l+"url/unsupported-option-value/",e);return Object.freeze(t),new Proxy(t,{get(e,r,a){switch(r){case Symbol.metroProxy:return!0;case Symbol.metroSource:return e;case"with":return function(...i){return h(e,...i)};case"filename":return e.pathname.split("/").pop();case"folderpath":return e.pathname.substring(0,e.pathname.lastIndexOf("\\")+1)}return e[r]instanceof Function?e[r].bind(e):e[r]}})}function g(...n){var o=new FormData;for(let t of n)if(t instanceof HTMLFormElement&&(t=new FormData(t)),t instanceof FormData)for(let e of t.entries())o.append(e[0],e[1]);else if(t&&typeof t=="object")for(let e of Object.entries(t))if(Array.isArray(e[1]))for(let r of e[1])o.append(e[0],r);else o.append(e[0],e[1]);else throw new f("metro.formdata: unknown option type "+l+"formdata/unknown-option-value/",t);return Object.freeze(o),new Proxy(o,{get:(t,e,r)=>{switch(e){case Symbol.metroProxy:return!0;case Symbol.metroSource:return t;case"with":return function(...a){return g(t,...a)}}return t[e]instanceof Function?t[e].bind(t):t[e]}})}var d={error:(n,...o)=>{console.error("\u24C2\uFE0F ",n,...o)},info:(n,...o)=>{console.info("\u24C2\uFE0F ",n,...o)},group:n=>{console.group("\u24C2\uFE0F "+n)},groupEnd:n=>{console.groupEnd("\u24C2\uFE0F "+n)}};function f(n,...o){return d.error(n,...o),new Error(n,...o)}var T={add(n,o){u.tracers[n]=o},delete(n){delete u.tracers[n]},clear(){u.tracers={}},group(){let n=0;return{request:(o,t)=>{n++,d.group(n),d.info(o?.url,o,t)},response:(o,t)=>{d.info(o?.body?o.body[Symbol.metroSource]:null,o,t),d.groupEnd(n),n--}}}};function P(n){return n=Object.assign({mimetype:"application/json",reviver:null,replacer:null,space:""},n),async(o,t)=>{S(o.headers.get("Accept"))||(o=o.with({headers:{Accept:n.mimetype}})),["POST","PUT","PATCH","QUERY"].includes(o.method)&&o.data&&typeof o.data=="object"&&!(o.data instanceof ReadableStream)&&(S(o.headers.get("content-type"))||(o=o.with({headers:{"Content-Type":n.mimetype}})),o=o.with({body:JSON.stringify(o.data,n.replacer,n.space)}));let e=await t(o);if(S(e.headers.get("content-type"))){let a=await e.clone().text();try{let i=JSON.parse(a,n.reviver);return e.with({body:i})}catch{}}return e}}var F=/^application\/([a-zA-Z0-9\-_]+\+)?json\b/;function S(n){return F.exec(n)}function x(n){return async(o,t)=>{let e=await t(o);if(!e.ok)if(n&&typeof n[e.status]=="function")e=n[e.status].apply(e,o);else throw new Error(e.status+": "+e.statusText,{cause:e});return e}}var O=Object.assign({},w,{mw:{jsonmw:P,thrower:x}});globalThis.metro||(globalThis.metro=O);var J=O;})(); +(()=>{var A=Object.defineProperty;var L=(n,r)=>{for(var t in r)A(n,t,{get:r[t],enumerable:!0})};var w={};L(w,{client:()=>U,formdata:()=>g,metroError:()=>f,request:()=>y,response:()=>b,trace:()=>T,url:()=>h});var l="https://metro.muze.nl/details/";Symbol.metroProxy||(Symbol.metroProxy=Symbol("isProxy"));Symbol.metroSource||(Symbol.metroSource=Symbol("source"));var u=class n{#e={url:typeof window<"u"?window.location:"https://localhost"};#t=["get","post","put","delete","patch","head","options","query"];static tracers={};constructor(...r){for(let t of r)if(typeof t=="string"||t instanceof String)this.#e.url=""+t;else if(t instanceof n)Object.assign(this.#e,t.#e);else if(t instanceof Function)this.#r([t]);else if(t&&typeof t=="object")for(let e in t)e=="middlewares"?this.#r(t[e]):typeof t[e]=="function"?this.#e[e]=t[e](this.#e[e],this.#e):this.#e[e]=t[e];this.#e.verbs&&(this.#t=this.#e.verbs,delete this.#e.verbs);for(let t of this.#t)this[t]=async function(...e){return this.fetch(y(this.#e,...e,{method:t.toUpperCase()}))};Object.freeze(this)}#r(r){typeof r=="function"&&(r=[r]);let t=r.findIndex(e=>typeof e!="function");if(t>=0)throw f("metro.client: middlewares must be a function or an array of functions "+l+"client/invalid-middlewares/",r[t]);Array.isArray(this.#e.middlewares)||(this.#e.middlewares=[]),this.#e.middlewares=this.#e.middlewares.concat(r)}fetch(r,t){if(r=y(r,t),!r.url)throw f("metro.client."+r.method.toLowerCase()+": Missing url parameter "+l+"client/fetch-missing-url/",r);if(t||(t={}),typeof t!="object"||t instanceof String)throw f("metro.client.fetch: Invalid options parameter "+l+"client/fetch-invalid-options/",t);let o=[async function(s){s[Symbol.metroProxy]&&(s=s[Symbol.metroSource]);let m=await fetch(s);return b(m)}].concat(this.#e?.middlewares?.slice()||[]);t=Object.assign({},this.#e,t);let a;for(let i of o)a=function(s,m){return async function(j){let p,v=Object.values(n.tracers);for(let c of v)c.request&&c.request.call(c,j,m);p=await m(j,s);for(let c of v)c.response&&c.response.call(c,p,m);return p}}(a,i);return a(r)}with(...r){return new n(this,...r)}};function U(...n){return new u(...n)}function E(n,r){let t=r||{};!t.url&&r.url&&(t.url=r.url);for(let e of["method","headers","body","mode","credentials","cache","redirect","referrer","referrerPolicy","integrity","keepalive","signal","priority","url"]){let o=n[e];if(!(typeof o>"u"||o==null))if(o?.[Symbol.metroProxy]&&(o=o[Symbol.metroSource]),typeof o=="function")t[e]=o(t[e],t);else if(e=="url")t.url=h(t.url,o);else if(e=="headers"){t.headers=new Headers(r.headers),o instanceof Headers||(o=new Headers(n.headers));for(let[a,i]of o.entries())t.headers.set(a,i)}else t[e]=o}return n instanceof Request&&n.data&&(t.body=n.data),t}function y(...n){let r={url:typeof window<"u"?window.location:"https://localhost/",duplex:"half"};for(let o of n)typeof o=="string"||o instanceof URL||o instanceof URLSearchParams?r.url=h(r.url,o):o&&(o instanceof FormData||o instanceof ReadableStream||o instanceof Blob||o instanceof ArrayBuffer||o instanceof DataView)?r.body=o:o&&typeof o=="object"&&Object.assign(r,E(o,r));let t=new Request(r.url,r),e=r.body;return e&&typeof e=="object"&&!(e instanceof String)&&!(e instanceof ReadableStream)&&!(e instanceof Blob)&&!(e instanceof ArrayBuffer)&&!(e instanceof DataView)&&!(e instanceof FormData)&&!(e instanceof URLSearchParams)&&(typeof TypedArray>"u"||!(e instanceof TypedArray))&&typeof e.toString=="function"&&(r.body=e.toString({headers:t.headers}),t=new Request(r.url,r)),Object.freeze(t),new Proxy(t,{get(o,a,i){switch(a){case Symbol.metroSource:return o;case Symbol.metroProxy:return!0;case"with":return function(...s){return e&&s.unshift({body:e}),y(o,...s)};case"data":return e}return o[a]instanceof Function?o[a].bind(o):o[a]}})}function R(n,r){let t=r||{};!t.url&&r.url&&(t.url=r.url);for(let e of["status","statusText","headers","body","url","type","redirected"]){let o=n[e];typeof o>"u"||o==null||(o?.[Symbol.metroProxy]&&(o=o[Symbol.metroSource]),typeof o=="function"?t[e]=o(t[e],t):e=="url"?t.url=new URL(o,t.url||"https://localhost/"):t[e]=o)}return n instanceof Response&&n.data&&(t.body=n.data),t}function b(...n){let r={};for(let o of n)typeof o=="string"?r.body=o:o instanceof Response?Object.assign(r,R(o,r)):o&&typeof o=="object"&&(o instanceof FormData||o instanceof Blob||o instanceof ArrayBuffer||o instanceof DataView||o instanceof ReadableStream||o instanceof URLSearchParams||o instanceof String||typeof TypedArray<"u"&&o instanceof TypedArray?r.body=o:Object.assign(r,R(o,r)));let t;r.body&&(t=r.body),[101,204,205,304].includes(r.status)&&(r.body=null);let e=new Response(r.body,r);return Object.freeze(e),new Proxy(e,{get(o,a,i){switch(a){case Symbol.metroProxy:return!0;case Symbol.metroSource:return o;case"with":return function(...s){return b(o,...s)};case"data":return t;case"ok":return o.status>=200&&o.status<400}return typeof o[a]=="function"?o[a].bind(o):o[a]}})}function k(n,r){typeof r=="function"?r(n.searchParams,n):(r=new URLSearchParams(r),r.forEach((t,e)=>{n.searchParams.append(e,t)}))}function h(...n){let r=["hash","host","hostname","href","password","pathname","port","protocol","username","search","searchParams"],t=new URL("https://localhost/");for(let e of n)if(typeof e=="string"||e instanceof String)t=new URL(e,t);else if(e instanceof URL||typeof Location<"u"&&e instanceof Location)t=new URL(e);else if(e instanceof URLSearchParams)k(t,e);else if(e&&typeof e=="object")for(let o in e)switch(o){case"search":typeof e.search=="function"?e.search(t.search,t):t.search=new URLSearchParams(e.search);break;case"searchParams":k(t,e.searchParams);break;default:if(!r.includes(o))throw f("metro.url: unknown url parameter "+l+"url/unknown-param-name/",o);if(typeof e[o]=="function")e[o](t[o],t);else if(typeof e[o]=="string"||e[o]instanceof String||typeof e[o]=="number"||e[o]instanceof Number||typeof e[o]=="boolean"||e[o]instanceof Boolean)t[o]=""+e[o];else if(typeof e[o]=="object"&&e[o].toString)t[o]=e[o].toString();else throw f("metro.url: unsupported value for "+o+" "+l+"url/unsupported-param-value/",n[o]);break}else throw f("metro.url: unsupported option value "+l+"url/unsupported-option-value/",e);return Object.freeze(t),new Proxy(t,{get(e,o,a){switch(o){case Symbol.metroProxy:return!0;case Symbol.metroSource:return e;case"with":return function(...i){return h(e,...i)};case"filename":return e.pathname.split("/").pop();case"folderpath":return e.pathname.substring(0,e.pathname.lastIndexOf("\\")+1)}return e[o]instanceof Function?e[o].bind(e):e[o]}})}function g(...n){var r=new FormData;for(let t of n)if(t instanceof HTMLFormElement&&(t=new FormData(t)),t instanceof FormData)for(let e of t.entries())r.append(e[0],e[1]);else if(t&&typeof t=="object")for(let e of Object.entries(t))if(Array.isArray(e[1]))for(let o of e[1])r.append(e[0],o);else r.append(e[0],e[1]);else throw new f("metro.formdata: unknown option type "+l+"formdata/unknown-option-value/",t);return Object.freeze(r),new Proxy(r,{get:(t,e,o)=>{switch(e){case Symbol.metroProxy:return!0;case Symbol.metroSource:return t;case"with":return function(...a){return g(t,...a)}}return t[e]instanceof Function?t[e].bind(t):t[e]}})}var d={error:(n,...r)=>{console.error("\u24C2\uFE0F ",n,...r)},info:(n,...r)=>{console.info("\u24C2\uFE0F ",n,...r)},group:n=>{console.group("\u24C2\uFE0F "+n)},groupEnd:n=>{console.groupEnd("\u24C2\uFE0F "+n)}};function f(n,...r){return d.error(n,...r),new Error(n,...r)}var T={add(n,r){u.tracers[n]=r},delete(n){delete u.tracers[n]},clear(){u.tracers={}},group(){let n=0;return{request:(r,t)=>{n++,d.group(n),d.info(r?.url,r,t)},response:(r,t)=>{d.info(r?.body?r.body[Symbol.metroSource]:null,r,t),d.groupEnd(n),n--}}}};function P(n){return n=Object.assign({mimetype:"application/json",reviver:null,replacer:null,space:""},n),async(r,t)=>{S(r.headers.get("Accept"))||(r=r.with({headers:{Accept:n.mimetype}})),["POST","PUT","PATCH","QUERY"].includes(r.method)&&r.data&&typeof r.data=="object"&&!(r.data instanceof ReadableStream)&&(S(r.headers.get("content-type"))||(r=r.with({headers:{"Content-Type":n.mimetype}})),r=r.with({body:JSON.stringify(r.data,n.replacer,n.space)}));let e=await t(r);if(S(e.headers.get("content-type"))){let a=await e.clone().text();try{let i=JSON.parse(a,n.reviver);return e.with({body:i})}catch{}}return e}}var F=/^application\/([a-zA-Z0-9\-_]+\+)?json\b/;function S(n){return F.exec(n)}function x(n){return async(r,t)=>{let e=await t(r);if(!e.ok)if(n&&typeof n[e.status]=="function")e=n[e.status].apply(e,r);else throw new Error(e.status+": "+e.statusText,{cause:e});return e}}var O=Object.assign({},w,{mw:{jsonmw:P,thrower:x}});globalThis.metro||(globalThis.metro=O);var J=O;})(); //# sourceMappingURL=everything.min.js.map diff --git a/dist/everything.min.js.map b/dist/everything.min.js.map index ac2644b..520470e 100644 --- a/dist/everything.min.js.map +++ b/dist/everything.min.js.map @@ -1,7 +1,7 @@ { "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 * @method fetch\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/', 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/fetch-missing-url/', 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|| options instanceof String) \n\t\t{\n\t\t\tthrow metroError('metro.client.fetch: Invalid options parameter '+metroURL+'client/fetch-invalid-options/', options)\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\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 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\tlet value = req[prop]\n\t\tif (typeof value=='undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = url(params.url, value)\n\t\t\t} else if (prop == 'headers') {\n\t\t\t\tparams.headers = new Headers(current.headers)\n\t\t\t\tif (!(value instanceof Headers)) {\n\t\t\t\t\tvalue = new Headers(req.headers)\n\t\t\t\t}\n\t\t\t\tfor (let [key, val] of value.entries()) {\n\t\t\t\t\tparams.headers.set(key, val)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (req instanceof Request && req.data) {\n\t\t// Request.body is always transformed into ReadableStreem\n\t\t// metro.request.data is the original body passed to Request()\n\t\tparams.body = req.data\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 r = new Request(requestParams.url, requestParams)\n\tlet data = requestParams.body\n\tif (data) {\n\t\tif (typeof data == 'object'\n\t\t\t&& !(data instanceof String)\n\t\t\t&& !(data instanceof ReadableStream)\n\t\t\t&& !(data instanceof Blob)\n\t\t\t&& !(data instanceof ArrayBuffer)\n\t\t\t&& !(data instanceof DataView)\n\t\t\t&& !(data instanceof FormData)\n\t\t\t&& !(data instanceof URLSearchParams)\n\t\t\t&& (typeof TypedArray=='undefined' || !(data instanceof TypedArray))\n\t\t) {\n\t\t\t// if we are here, body is set with an object of a type\n\t\t\t// not natively understood by Request, coerce it to a string\n\t\t\t// using toString({headers}) instead of just toString()\n\t\t\tif (typeof data.toString == 'function') {\n\t\t\t\trequestParams.body = data.toString({headers:r.headers})\n\t\t\t\tr = new Request(requestParams.url, requestParams)\n\t\t\t}\n\t\t}\n\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.metroSource:\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 (data) { // data is kept in a seperate value, if it set earlier\n\t\t\t\t\t\t\toptions.unshift({ body: data }) // 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 'data':\n\t\t\t\t\treturn data\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (target[prop] instanceof Function) {\n\t\t\t\tif (prop === 'clone') {\n\t\t\t\t\t// TODO: set req.data as the body of the clone\n\t\t\t\t}\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\tlet value = res[prop]\n\t\tif (typeof value == 'undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = new URL(value, params.url || 'https://localhost/')\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (res instanceof Response && res.data) {\n\t\t// Response.body is always transformed into ReadableStreem FIXME: check this\n\t\t// metro.response.data is the original body passed to Response()\n\t\tparams.body = res.data\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 data = undefined\n\tif (responseParams.body) {\n\t\tdata = responseParams.body\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 'data':\n\t\t\t\t\t// body is turned into ReadableStream\n\t\t\t\t\t// data is the original body param\n\t\t\t\t\treturn data\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}\n\t\t\tif (typeof target[prop] == '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 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\tswitch(param) {\n\t\t\t\t\tcase 'search':\n\t\t\t\t\t\tif (typeof option.search == 'function') {\n\t\t\t\t\t\t\toption.search(u.search, u)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tu.search = new URLSearchParams(option.search)\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t\tcase 'searchParams':\n\t\t\t\t\t\tappendSearchParams(u, option.searchParams)\n\t\t\t\t\tbreak\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (!validParams.includes(param)) {\n\t\t\t\t\t\t\tthrow metroError('metro.url: unknown url parameter '+metroURL+'url/unknown-param-name/', param)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (typeof option[param] == 'function') {\n\t\t\t\t\t\t\toption[param](u[param], u)\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\ttypeof option[param] == 'string' || option[param] instanceof String \n\t\t\t\t\t\t\t|| typeof option[param] == 'number' || option[param] instanceof Number\n\t\t\t\t\t\t\t|| typeof option[param] == 'boolean' || option[param] instanceof Boolean\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tu[param] = ''+option[param]\n\t\t\t\t\t\t} else if (typeof option[param] == 'object' && option[param].toString) {\n\t\t\t\t\t\t\tu[param] = option[param].toString()\n\t\t\t\t\t\t} else {\n\t\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\t}\n\t\t\t\t\tbreak\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 'filename':\n\t\t\t\t\treturn target.pathname.split('/').pop()\n\t\t\t\tbreak\n\t\t\t\tcase 'folderpath':\n\t\t\t\t\treturn target.pathname.substring(0,target.pathname.lastIndexOf('\\\\')+1)\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\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 HTMLFormElement) {\n\t\t\toption = new FormData(option)\n\t\t}\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 '+metroURL+'formdata/unknown-option-value/', 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\t//TODO: add toString() that can check\n\t\t\t\t//headers param: toString({headers:request.headers})\n\t\t\t\t//for the content-type\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}\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\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\tmimetype: 'application/json',\n\t\treviver: null,\n\t\treplacer: null,\n\t\tspace: ''\n\t}, options)\n\n\treturn async (req, next) => {\n\t\tif (!isJSON(req.headers.get('Accept'))) {\n\t\t\treq = req.with({\n\t\t\t\theaders: {\n\t 'Accept': options.mimetype\n\t }\n\t })\n\t\t}\n\t\tif (['POST','PUT','PATCH','QUERY'].includes(req.method)) {\n\t\t\tif (req.data && typeof req.data=='object' && !(req.data instanceof ReadableStream)) {\n\t\t\t\tif (!isJSON(req.headers.get('content-type'))) {\n\t\t\t\t\treq = req.with({\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t'Content-Type':options.mimetype,\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treq = req.with({\n\t\t\t\t\tbody: JSON.stringify(req.data, options.replacer, options.space)\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tlet res = await next(req)\n\t\tif (isJSON(res.headers.get('content-type'))) {\n\t\t\tlet tempRes = res.clone()\n\t\t\tlet body = await tempRes.text()\n\t\t\ttry {\n\t\t\t\tlet json = JSON.parse(body, options.reviver)\n\t\t\t\treturn res.with({\n\t\t\t\t\tbody: json\n\t\t\t\t})\n\t\t\t} catch(e) {\n\t\t\t\t// ignore parse errors\n\t\t\t}\n\t\t} \n\t\treturn res\n\t}\n}\n\nconst jsonRE = /^application\\/([a-zA-Z0-9\\-_]+\\+)?json\\b/\nfunction isJSON(contentType) {\n\treturn jsonRE.exec(contentType)\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 m from './metro.mjs'\nimport jsonmw from './mw/json.mjs'\nimport thrower from './mw/thrower.mjs'\n\nconst metro = Object.assign({}, m, {\n\tmw: {\n\t\tjsonmw,\n\t\tthrower\n\t}\n})\n\nif (!globalThis.metro) {\n\tglobalThis.metro = metro\n}\n\nexport default metro"], - "mappings": "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", + "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 * @method fetch\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/', 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/fetch-missing-url/', 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|| options instanceof String) \n\t\t{\n\t\t\tthrow metroError('metro.client.fetch: Invalid options parameter '+metroURL+'client/fetch-invalid-options/', options)\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\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 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\tlet value = req[prop]\n\t\tif (typeof value=='undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = url(params.url, value)\n\t\t\t} else if (prop == 'headers') {\n\t\t\t\tparams.headers = new Headers(current.headers)\n\t\t\t\tif (!(value instanceof Headers)) {\n\t\t\t\t\tvalue = new Headers(req.headers)\n\t\t\t\t}\n\t\t\t\tfor (let [key, val] of value.entries()) {\n\t\t\t\t\tparams.headers.set(key, val)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (req instanceof Request && req.data) {\n\t\t// Request.body is always transformed into ReadableStreem\n\t\t// metro.request.data is the original body passed to Request()\n\t\tparams.body = req.data\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 r = new Request(requestParams.url, requestParams)\n\tlet data = requestParams.body\n\tif (data) {\n\t\tif (typeof data == 'object'\n\t\t\t&& !(data instanceof String)\n\t\t\t&& !(data instanceof ReadableStream)\n\t\t\t&& !(data instanceof Blob)\n\t\t\t&& !(data instanceof ArrayBuffer)\n\t\t\t&& !(data instanceof DataView)\n\t\t\t&& !(data instanceof FormData)\n\t\t\t&& !(data instanceof URLSearchParams)\n\t\t\t&& (typeof TypedArray=='undefined' || !(data instanceof TypedArray))\n\t\t) {\n\t\t\t// if we are here, body is set with an object of a type\n\t\t\t// not natively understood by Request, coerce it to a string\n\t\t\t// using toString({headers}) instead of just toString()\n\t\t\tif (typeof data.toString == 'function') {\n\t\t\t\trequestParams.body = data.toString({headers:r.headers})\n\t\t\t\tr = new Request(requestParams.url, requestParams)\n\t\t\t}\n\t\t}\n\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.metroSource:\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 (data) { // data is kept in a seperate value, if it set earlier\n\t\t\t\t\t\t\toptions.unshift({ body: data }) // 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 'data':\n\t\t\t\t\treturn data\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif (target[prop] instanceof Function) {\n\t\t\t\tif (prop === 'clone') {\n\t\t\t\t\t// TODO: set req.data as the body of the clone\n\t\t\t\t}\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\tlet value = res[prop]\n\t\tif (typeof value == 'undefined' || value == null) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value?.[Symbol.metroProxy]) {\n\t\t\tvalue = value[Symbol.metroSource]\n\t\t}\n\t\tif (typeof value == 'function') {\n\t\t\tparams[prop] = value(params[prop], params)\n\t\t} else {\n\t\t\tif (prop == 'url') {\n\t\t\t\tparams.url = new URL(value, params.url || 'https://localhost/')\n\t\t\t} else {\n\t\t\t\tparams[prop] = value\n\t\t\t}\n\t\t}\n\t}\n\tif (res instanceof Response && res.data) {\n\t\t// Response.body is always transformed into ReadableStreem FIXME: check this\n\t\t// metro.response.data is the original body passed to Response()\n\t\tparams.body = res.data\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 data = undefined\n\tif (responseParams.body) {\n\t\tdata = responseParams.body\n\t}\n\t// if response status is 'null body status', don't set a body\n\t// that is response.status in [101, 204, 205, 304 ] \n\t// see: https://fetch.spec.whatwg.org/#statuses\n\tif ([101, 204, 205, 304 ].includes(responseParams.status)) {\n\t\tresponseParams.body = null\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 'data':\n\t\t\t\t\t// body is turned into ReadableStream\n\t\t\t\t\t// data is the original body param\n\t\t\t\t\treturn data\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}\n\t\t\tif (typeof target[prop] == '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 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\tswitch(param) {\n\t\t\t\t\tcase 'search':\n\t\t\t\t\t\tif (typeof option.search == 'function') {\n\t\t\t\t\t\t\toption.search(u.search, u)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tu.search = new URLSearchParams(option.search)\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t\tcase 'searchParams':\n\t\t\t\t\t\tappendSearchParams(u, option.searchParams)\n\t\t\t\t\tbreak\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (!validParams.includes(param)) {\n\t\t\t\t\t\t\tthrow metroError('metro.url: unknown url parameter '+metroURL+'url/unknown-param-name/', param)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (typeof option[param] == 'function') {\n\t\t\t\t\t\t\toption[param](u[param], u)\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\ttypeof option[param] == 'string' || option[param] instanceof String \n\t\t\t\t\t\t\t|| typeof option[param] == 'number' || option[param] instanceof Number\n\t\t\t\t\t\t\t|| typeof option[param] == 'boolean' || option[param] instanceof Boolean\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tu[param] = ''+option[param]\n\t\t\t\t\t\t} else if (typeof option[param] == 'object' && option[param].toString) {\n\t\t\t\t\t\t\tu[param] = option[param].toString()\n\t\t\t\t\t\t} else {\n\t\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\t}\n\t\t\t\t\tbreak\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 'filename':\n\t\t\t\t\treturn target.pathname.split('/').pop()\n\t\t\t\tbreak\n\t\t\t\tcase 'folderpath':\n\t\t\t\t\treturn target.pathname.substring(0,target.pathname.lastIndexOf('\\\\')+1)\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\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 HTMLFormElement) {\n\t\t\toption = new FormData(option)\n\t\t}\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 '+metroURL+'formdata/unknown-option-value/', 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\t//TODO: add toString() that can check\n\t\t\t\t//headers param: toString({headers:request.headers})\n\t\t\t\t//for the content-type\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}\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\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\tmimetype: 'application/json',\n\t\treviver: null,\n\t\treplacer: null,\n\t\tspace: ''\n\t}, options)\n\n\treturn async (req, next) => {\n\t\tif (!isJSON(req.headers.get('Accept'))) {\n\t\t\treq = req.with({\n\t\t\t\theaders: {\n\t 'Accept': options.mimetype\n\t }\n\t })\n\t\t}\n\t\tif (['POST','PUT','PATCH','QUERY'].includes(req.method)) {\n\t\t\tif (req.data && typeof req.data=='object' && !(req.data instanceof ReadableStream)) {\n\t\t\t\tif (!isJSON(req.headers.get('content-type'))) {\n\t\t\t\t\treq = req.with({\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t'Content-Type':options.mimetype,\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treq = req.with({\n\t\t\t\t\tbody: JSON.stringify(req.data, options.replacer, options.space)\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tlet res = await next(req)\n\t\tif (isJSON(res.headers.get('content-type'))) {\n\t\t\tlet tempRes = res.clone()\n\t\t\tlet body = await tempRes.text()\n\t\t\ttry {\n\t\t\t\tlet json = JSON.parse(body, options.reviver)\n\t\t\t\treturn res.with({\n\t\t\t\t\tbody: json\n\t\t\t\t})\n\t\t\t} catch(e) {\n\t\t\t\t// ignore parse errors\n\t\t\t}\n\t\t} \n\t\treturn res\n\t}\n}\n\nconst jsonRE = /^application\\/([a-zA-Z0-9\\-_]+\\+)?json\\b/\nfunction isJSON(contentType) {\n\treturn jsonRE.exec(contentType)\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 m from './metro.mjs'\nimport jsonmw from './mw/json.mjs'\nimport thrower from './mw/thrower.mjs'\n\nconst metro = Object.assign({}, m, {\n\tmw: {\n\t\tjsonmw,\n\t\tthrower\n\t}\n})\n\nif (!globalThis.metro) {\n\tglobalThis.metro = metro\n}\n\nexport default metro"], + "mappings": "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", "names": ["metro_exports", "__export", "client", "formdata", "metroError", "request", "response", "trace", "url", "metroURL", "Client", "_Client", "#options", "#verbs", "options", "option", "#addMiddlewares", "param", "verb", "middlewares", "index", "m", "req", "res", "next", "middleware", "tracers", "tracer", "getRequestParams", "req", "current", "params", "prop", "value", "url", "key", "val", "request", "options", "requestParams", "option", "r", "data", "target", "receiver", "getResponseParams", "res", "response", "responseParams", "appendSearchParams", "validParams", "u", "param", "metroError", "metroURL", "formdata", "entry", "metroConsole", "message", "details", "name", "trace", "tracer", "Client", "group", "middleware", "jsonmw", "options", "req", "next", "isJSON", "res", "body", "json", "jsonRE", "contentType", "thrower", "options", "req", "next", "res", "metro", "metro_exports", "jsonmw", "thrower", "everything_default"] } diff --git a/package.json b/package.json index c74234c..9ad2eda 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@muze-nl/metro", - "version": "0.6.4", + "version": "0.6.5", "description": "http client with middleware support", "type": "module", "source": [ "src/browser.mjs", "src/everything.mjs" ],