@lowerdeck/rpc-server 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var e=require("@lowerdeck/error"),r=require("@lowerdeck/execution-context"),t=require("@lowerdeck/id"),n=require("@lowerdeck/memo"),o=require("@lowerdeck/sentry"),a=require("@lowerdeck/serialize"),i=require("@lowerdeck/validation");function s(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach(function(t){if("default"!==t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})}}),r.default=e,r}var u=/*#__PURE__*/s(require("cookie"));function c(e,r){(null==r||r>e.length)&&(r=e.length);for(var t=0,n=Array(r);t<r;t++)n[t]=e[t];return n}function l(e,r){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,r){if(e){if("string"==typeof e)return c(e,r);var t={}.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?c(e,r):void 0}}(e))||r&&e&&"number"==typeof e.length){t&&(e=t);var n=0;return function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function d(){return d=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)({}).hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e},d.apply(null,arguments)}const f="undefined"!=typeof Symbol?Symbol.iterator||(Symbol.iterator=Symbol("Symbol.iterator")):"@@iterator";function h(e,r,t){if(!e.s){if(t instanceof p){if(!t.s)return void(t.o=h.bind(null,e,r));1&r&&(r=t.s),t=t.v}if(t&&t.then)return void t.then(h.bind(null,e,r),h.bind(null,e,2));e.s=r,e.v=t;var n=e.o;n&&n(e)}}var p=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(r,t){var n=new e,o=this.s;if(o){var a=1&o?r:t;if(a){try{h(n,1,a(this.v))}catch(e){h(n,2,e)}return n}return this}return this.o=function(e){try{var o=e.v;1&e.s?h(n,1,r?r(o):o):t?h(n,1,t(o)):h(n,2,o)}catch(e){h(n,2,e)}},n},e}();function v(e){return e instanceof p&&1&e.s}var m=/*#__PURE__*/function(){function e(e){void 0===e&&(e=[]),this._middleware=void 0,this._middleware=e}var r=e.prototype;return r.use=function(r,t){return new e([].concat(this._middleware,[function(e){try{var n,o=function(t){if(n)return t;var o=r(e);return a&&e.sharedMiddlewareMemo.set(a,o),Promise.resolve(o)},a=null==t||null==t.getSharedMemoKey?void 0:t.getSharedMemoKey(e),i=function(){if(a&&e.sharedMiddlewareMemo.has(a))return Promise.resolve(e.sharedMiddlewareMemo.get(a)).then(function(e){return n=1,e})}();return Promise.resolve(i&&i.then?i.then(o):o(i))}catch(e){return Promise.reject(e)}}]))},r.createMiddleware=function(e,r){return function(t){return function(n){try{var o,a=function(r){if(o)return r;var a=e(n,t);return i&&n.sharedMiddlewareMemo.set(i,a),Promise.resolve(a)},i=null==r||null==r.getSharedMemoKey?void 0:r.getSharedMemoKey(n,t),s=function(){if(i&&n.sharedMiddlewareMemo.has(i))return Promise.resolve(n.sharedMiddlewareMemo.get(i)).then(function(e){return o=1,e})}();return Promise.resolve(s&&s.then?s.then(a):a(s))}catch(e){return Promise.reject(e)}}}},r.handler=function(){return new y([].concat(this._middleware))},r.controller=function(e){return e},e}(),y=/*#__PURE__*/function(){function r(e){void 0===e&&(e=[]),this._middleware=void 0,this._handler=void 0,this._validation=void 0,this._middleware=e}var t=r.prototype;return t.do=function(e){if(null!=this._handler)throw new Error("Handler already defined");return this._handler=e,this},t.use=function(e){return this._middleware.push(e),this},t.input=function(e){if(null!=this._validation)throw new Error("Input validation already defined");return this._validation=e,this},t.run=function(r,t){try{var n=function(){return Promise.resolve(o._handler(d({},s,{input:a,body:void 0}))).then(function(e){return{response:e}})},o=this;if(!o._handler)throw new Error("Handler not defined");var a=r.body;if(o._validation){var i=o._validation.validate(r.body);if(!i.success)throw new e.ServiceError(e.validationError({errors:i.errors,entity:"call_data"}));a=i.value}var s=d({},t,r,{body:a}),u=function(e,r){if("function"==typeof e[f]){var t,n,o,a=function(e){try{for(;!(t=i.next()).done;)if((e=r(t.value))&&e.then){if(!v(e))return void e.then(a,o||(o=h.bind(null,n=new p,2)));e=e.v}n?h(n,1,e):n=e}catch(e){h(n||(n=new p),2,e)}},i=e[f]();if(a(),i.return){var s=function(e){try{t.done||i.return()}catch(e){}return e};if(n&&n.then)return n.then(s,function(e){throw s(e)});s()}return n}if(!("length"in e))throw new TypeError("Object is not iterable");for(var u=[],c=0;c<e.length;c++)u.push(e[c]);return function(e,r){var t,n,o=-1;return function a(i){try{for(;++o<e.length;)if((i=r(o))&&i.then){if(!v(i))return void i.then(a,n||(n=h.bind(null,t=new p,2)));i=i.v}t?h(t,1,i):t=i}catch(e){h(t||(t=new p),2,e)}}(),t}(u,function(e){return r(u[e])})}(o._middleware,function(e){return Promise.resolve(e(s)).then(function(e){e&&(s=d({},s,e))})});return Promise.resolve(u&&u.then?u.then(n):n())}catch(e){return Promise.reject(e)}},r}(),g=o.getSentry(),w=i.v.object({calls:i.v.array(i.v.object({id:i.v.string(),name:i.v.string(),payload:i.v.any()}))}),b=o.getSentry();exports.Group=m,exports.Handler=y,exports.createServer=function(r){return function(t){var n=function(e){return Object.entries(e).flatMap(function(e){var r=e[0],t=e[1];return t instanceof y?[r]:"object"==typeof t?n(t).map(function(e){return r+":"+e}):[]})};return{handlerNames:n(t),runMany:function(n,o){try{return Promise.resolve(Promise.all(o.calls.map(function(a,i){try{return Promise.resolve(function(n,o,a){try{var i=d({},n,{body:o.payload});return Promise.resolve(function(r,a){try{var s=(u=function(e){for(var r=e.split(":"),n=t;n&&r.length>0;)if(!(n=n[r.shift()]))return null;return n&&n instanceof y?n:null}(o.name))?Promise.resolve(u.run(i,{})).then(function(e){return{status:200,request:n,response:e.response}}):{request:i,status:404,response:e.notFoundError({entity:"handler"}).toResponse()}}catch(e){return a(e)}var u;return s&&s.then?s.then(void 0,a):s}(0,function(t){return console.error(t),e.isServiceError(t)?(t.data.status>=500&&b.captureException(t,{tags:{reqId:a}}),{request:i,status:t.data.status,response:t.toResponse()}):(b.captureException(t,{tags:{reqId:a}}),null==r.onError||r.onError({callName:o.name,callId:o.id,request:n,error:t,reqId:a}),{request:i,status:500,response:e.internalServerError().toResponse()})}))}catch(e){return Promise.reject(e)}}(n,a,o.requestId)).then(function(e){try{null==r.onRequest||r.onRequest({reqId:o.requestId,callId:a.id,callName:a.name,request:e.request,response:{status:e.status,body:e.response}})}catch(e){b.captureException(e),console.error(e)}return{__typename:"rpc.response.call",id:a.id,name:a.name,status:e.status,result:e.response}})}catch(e){return Promise.reject(e)}}))).then(function(e){return{status:Math.max.apply(Math,e.map(function(e){return e.status})),body:{__typename:"rpc.response",calls:e}}})}catch(e){return Promise.reject(e)}}}}},exports.rpcMux=function(o,i){var s=new Map(i.flatMap(function(e,r){return e.handlerNames.map(function(e){return[e,r]})}));return{path:o.path,fetch:function(c){try{var d,f,h,p=function(o){var d,f,p,v;if(h)return o;var y=c.headers.get("sentry-trace"),P=null!=(d=Array.isArray(y)?y.join(","):y)?d:void 0,q=c.headers.get("baggage"),M=function(e){if("string"==typeof e){var r=e.split(",").map(function(e){return e.trim()}).filter(Boolean);return r.length>0?r[0]:void 0}}(null!=(f=null!=(p=null!=(v=c.headers.get("lowerdeck-connecting-ip"))?v:c.headers.get("cf-connecting-ip"))?p:c.headers.get("x-forwarded-for"))?f:c.headers.get("x-real-ip")),_=new Headers;if(m)for(var x=0,E=Object.entries(S);x<E.length;x++){var O=E[x];_.append(O[0],O[1])}return Promise.resolve(g.withIsolationScope(function(){try{return Promise.resolve(g.continueTrace({sentryTrace:P,baggage:q},function(){try{var o,d;return Promise.resolve(g.startSpan({name:"rpc request",op:"rpc.server",attributes:{ip:M,transport:"http",ua:null!=(o=c.headers.get("user-agent"))?o:"",origin:null!=(d=c.headers.get("origin"))?d:""}},function(){try{try{var o,d=[],f=t.generateCustomId("req_"),h=n.memo(function(){var e;return u.parse(null!=(e=c.headers.get("cookie"))?e:"")}),p={url:c.url,headers:c.headers,query:b.searchParams,body:j,rawBody:j,ip:M,requestId:f,getCookies:function(){return h()},getCookie:function(e){return h()[e]},setCookie:function(e,r,t){var n=u.serialize(e,r,t);_.append("Set-Cookie",n)},beforeSend:function(e){d.push(e)},sharedMiddlewareMemo:new Map,appendHeaders:function(e){for(var r=0,t=Object.entries(e);r<t.length;r++){var n=t[r],o=n[0],a=n[1];if(Array.isArray(a))for(var i,s=l(a);!(i=s()).done;)_.append(o,i.value);else _.append(o,a)}}};return g.getCurrentScope().setContext("rpc.request",{url:c.url,query:Object.fromEntries(b.searchParams.entries())}),g.getCurrentScope().addAttachment({filename:"rpc.request.body.json",data:j,contentType:"application/json"}),Promise.resolve(r.provideExecutionContext(r.createExecutionContext({type:"request",contextId:f,ip:null!=M?M:"0.0.0.0",userAgent:null!=(o=c.headers.get("user-agent"))?o:""}),function(){try{var r=new Map,n={body:{__typename:"rpc.response",calls:[]},status:200},o=b.pathname.split("/").filter(Boolean),u=o[o.length-1];if("$"==u[0]){var c,h=u.slice(1),v=s.get(h);if(null==v)return Promise.resolve(new Response(JSON.stringify(e.notFoundError({entity:"handler"}).toResponse()),{status:404,headers:_}));var m=null!=(c=r.get(v))?c:[];m.push({id:t.generateCustomId("call_"),name:h,payload:j}),r.set(v,m)}else{var y=w.validate(j);if(!y.success)return Promise.resolve(new Response(JSON.stringify(e.validationError({errors:y.errors,entity:"request_data"}).toResponse()),{status:406,headers:_}));for(var g,P=l(y.value.calls);!(g=P()).done;){var S,q=g.value,M=s.get(q.name);if(null==M)return Promise.resolve(new Response(JSON.stringify(e.notFoundError({entity:"handler"}).toResponse()),{status:404,headers:_}));var x=null!=(S=r.get(M))?S:[];x.push(q),r.set(M,x)}}return Promise.resolve(Promise.all(Array.from(r.entries()).map(function(e){var r=e[0],t=e[1];try{return Promise.resolve(i[r].runMany(p,{requestId:f,calls:t})).then(function(e){var r;n.status=Math.max(n.status,e.status),(r=n.body.calls).push.apply(r,e.body.calls)})}catch(e){return Promise.reject(e)}}))).then(function(){return _.append("x-req-id",f),_.append("content-type","application/rpc+json"),_.append("x-powered-by","lowerdeck RPC"),Promise.resolve(Promise.all(d.map(function(e){return e()}))).then(function(){return new Response(a.serialize.encode(n.body),{status:n.status,headers:_})})})}catch(e){return Promise.reject(e)}}))}catch(r){return console.error(r),g.captureException(r),Promise.resolve(new Response(JSON.stringify(e.internalServerError().toResponse()),{status:500,headers:_}))}}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}}))},v=null!=(d=c.headers.get("origin"))?d:"",m=!1;if(o.cors&&"domains"in o.cors)try{var y=new URL(v).hostname.split(".").slice(-2).join(".");m=o.cors.domains.includes(y)}catch(e){}else o.cors&&"check"in o.cors&&(m=o.cors.check(v));var b=new URL(c.url),P=null==(f=o.cors)||null==(f=f.headers)?void 0:f.join(", ");P&&(P=(", "+P).trim());var S=m?{"access-control-allow-origin":v,"access-control-allow-methods":"POST, OPTIONS","access-control-allow-headers":"Content-Type, Authorization, Baggage, Sentry-Trace"+(null!=P?P:""),"access-control-max-age":"604800","access-control-allow-credentials":"true"}:{};if("OPTIONS"==c.method)return Promise.resolve(m?new Response(null,{status:204,headers:S}):new Response(null,{status:403}));var j=null,q=function(e,r){try{var t=e()}catch(e){return r()}return t&&t.then?t.then(void 0,r):t}(function(){var e=a.serialize.decode;return Promise.resolve(c.text()).then(function(r){j=e.call(a.serialize,r)})},function(){var r=new Response(JSON.stringify(e.notAcceptableError({message:"Invalid JSON"}).toResponse()),{status:406});return h=1,r});return Promise.resolve(q&&q.then?q.then(p):p(q))}catch(e){return Promise.reject(e)}}}};
1
+ var e=require("@lowerdeck/error"),r=require("@lowerdeck/execution-context"),t=require("@lowerdeck/id"),n=require("@lowerdeck/memo"),o=require("@lowerdeck/sentry"),a=require("@lowerdeck/serialize"),i=require("@lowerdeck/validation");function s(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach(function(t){if("default"!==t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})}}),r.default=e,r}var u=/*#__PURE__*/s(require("cookie"));function c(e,r){(null==r||r>e.length)&&(r=e.length);for(var t=0,n=Array(r);t<r;t++)n[t]=e[t];return n}function l(e,r){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,r){if(e){if("string"==typeof e)return c(e,r);var t={}.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?c(e,r):void 0}}(e))||r&&e&&"number"==typeof e.length){t&&(e=t);var n=0;return function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function d(){return d=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)({}).hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e},d.apply(null,arguments)}const f="undefined"!=typeof Symbol?Symbol.iterator||(Symbol.iterator=Symbol("Symbol.iterator")):"@@iterator";function h(e,r,t){if(!e.s){if(t instanceof p){if(!t.s)return void(t.o=h.bind(null,e,r));1&r&&(r=t.s),t=t.v}if(t&&t.then)return void t.then(h.bind(null,e,r),h.bind(null,e,2));e.s=r,e.v=t;var n=e.o;n&&n(e)}}var p=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(r,t){var n=new e,o=this.s;if(o){var a=1&o?r:t;if(a){try{h(n,1,a(this.v))}catch(e){h(n,2,e)}return n}return this}return this.o=function(e){try{var o=e.v;1&e.s?h(n,1,r?r(o):o):t?h(n,1,t(o)):h(n,2,o)}catch(e){h(n,2,e)}},n},e}();function v(e){return e instanceof p&&1&e.s}var m=/*#__PURE__*/function(){function e(e){void 0===e&&(e=[]),this._middleware=void 0,this._middleware=e}var r=e.prototype;return r.use=function(r,t){return new e([].concat(this._middleware,[function(e){try{var n,o=function(t){if(n)return t;var o=r(e);return a&&e.sharedMiddlewareMemo.set(a,o),Promise.resolve(o)},a=null==t||null==t.getSharedMemoKey?void 0:t.getSharedMemoKey(e),i=function(){if(a&&e.sharedMiddlewareMemo.has(a))return Promise.resolve(e.sharedMiddlewareMemo.get(a)).then(function(e){return n=1,e})}();return Promise.resolve(i&&i.then?i.then(o):o(i))}catch(e){return Promise.reject(e)}}]))},r.createMiddleware=function(e,r){return function(t){return function(n){try{var o,a=function(r){if(o)return r;var a=e(n,t);return i&&n.sharedMiddlewareMemo.set(i,a),Promise.resolve(a)},i=null==r||null==r.getSharedMemoKey?void 0:r.getSharedMemoKey(n,t),s=function(){if(i&&n.sharedMiddlewareMemo.has(i))return Promise.resolve(n.sharedMiddlewareMemo.get(i)).then(function(e){return o=1,e})}();return Promise.resolve(s&&s.then?s.then(a):a(s))}catch(e){return Promise.reject(e)}}}},r.handler=function(){return new y([].concat(this._middleware))},r.controller=function(e){return e},e}(),y=/*#__PURE__*/function(){function r(e){void 0===e&&(e=[]),this._middleware=void 0,this._handler=void 0,this._validation=void 0,this._middleware=e}var t=r.prototype;return t.do=function(e){if(null!=this._handler)throw new Error("Handler already defined");return this._handler=e,this},t.use=function(e){return this._middleware.push(e),this},t.input=function(e){if(null!=this._validation)throw new Error("Input validation already defined");return this._validation=e,this},t.run=function(r,t){try{var n=function(){return Promise.resolve(o._handler(d({},s,{input:a,body:void 0}))).then(function(e){return{response:e}})},o=this;if(!o._handler)throw new Error("Handler not defined");var a=r.body;if(o._validation){var i=o._validation.validate(r.body);if(!i.success)throw new e.ServiceError(e.validationError({errors:i.errors,entity:"call_data"}));a=i.value}var s=d({},t,r,{body:a}),u=function(e,r){if("function"==typeof e[f]){var t,n,o,a=function(e){try{for(;!(t=i.next()).done;)if((e=r(t.value))&&e.then){if(!v(e))return void e.then(a,o||(o=h.bind(null,n=new p,2)));e=e.v}n?h(n,1,e):n=e}catch(e){h(n||(n=new p),2,e)}},i=e[f]();if(a(),i.return){var s=function(e){try{t.done||i.return()}catch(e){}return e};if(n&&n.then)return n.then(s,function(e){throw s(e)});s()}return n}if(!("length"in e))throw new TypeError("Object is not iterable");for(var u=[],c=0;c<e.length;c++)u.push(e[c]);return function(e,r){var t,n,o=-1;return function a(i){try{for(;++o<e.length;)if((i=r(o))&&i.then){if(!v(i))return void i.then(a,n||(n=h.bind(null,t=new p,2)));i=i.v}t?h(t,1,i):t=i}catch(e){h(t||(t=new p),2,e)}}(),t}(u,function(e){return r(u[e])})}(o._middleware,function(e){return Promise.resolve(e(s)).then(function(e){e&&(s=d({},s,e))})});return Promise.resolve(u&&u.then?u.then(n):n())}catch(e){return Promise.reject(e)}},r}(),g=o.getSentry(),w=i.v.object({calls:i.v.array(i.v.object({id:i.v.string(),name:i.v.string(),payload:i.v.any()}))}),b=o.getSentry();exports.Group=m,exports.Handler=y,exports.createServer=function(r){return function(t){var n=function(e){return Object.entries(e).flatMap(function(e){var r=e[0],t=e[1];return t instanceof y?[r]:"object"==typeof t?n(t).map(function(e){return r+":"+e}):[]})};return{handlerNames:n(t),runMany:function(n,o){try{return Promise.resolve(Promise.all(o.calls.map(function(a,i){try{return Promise.resolve(function(n,o,a){try{var i=d({},n,{body:o.payload});return Promise.resolve(function(r,a){try{var s=(u=function(e){for(var r=e.split(":"),n=t;n&&r.length>0;)if(!(n=n[r.shift()]))return null;return n&&n instanceof y?n:null}(o.name))?Promise.resolve(u.run(i,{})).then(function(e){return{status:200,request:n,response:e.response}}):{request:i,status:404,response:e.notFoundError({entity:"handler"}).toResponse()}}catch(e){return a(e)}var u;return s&&s.then?s.then(void 0,a):s}(0,function(t){return console.error(t),e.isServiceError(t)?(t.data.status>=500&&b.captureException(t,{tags:{reqId:a}}),{request:i,status:t.data.status,response:t.toResponse()}):(b.captureException(t,{tags:{reqId:a}}),null==r.onError||r.onError({callName:o.name,callId:o.id,request:n,error:t,reqId:a}),{request:i,status:500,response:e.internalServerError().toResponse()})}))}catch(e){return Promise.reject(e)}}(n,a,o.requestId)).then(function(e){try{null==r.onRequest||r.onRequest({reqId:o.requestId,callId:a.id,callName:a.name,request:e.request,response:{status:e.status,body:e.response}})}catch(e){b.captureException(e),console.error(e)}return{__typename:"rpc.response.call",id:a.id,name:a.name,status:e.status,result:e.response}})}catch(e){return Promise.reject(e)}}))).then(function(e){return{status:Math.max.apply(Math,e.map(function(e){return e.status})),body:{__typename:"rpc.response",calls:e}}})}catch(e){return Promise.reject(e)}}}}},exports.rpcMux=function(o,i){var s=new Map(i.flatMap(function(e,r){return e.handlerNames.map(function(e){return[e,r]})}));return{path:o.path,fetch:function(c){try{var d,f,h,p=function(o){var d,f,p,v;if(h)return o;var y=c.headers.get("sentry-trace"),P=null!=(d=Array.isArray(y)?y.join(","):y)?d:void 0,q=c.headers.get("baggage"),M=function(e){if("string"==typeof e){var r=e.split(",").map(function(e){return e.trim()}).filter(Boolean);return r.length>0?r[0]:void 0}}(null!=(f=null!=(p=null!=(v=c.headers.get("lowerdeck-connecting-ip"))?v:c.headers.get("cf-connecting-ip"))?p:c.headers.get("x-forwarded-for"))?f:c.headers.get("x-real-ip")),_=new Headers;if(m)for(var x=0,E=Object.entries(S);x<E.length;x++){var O=E[x];_.append(O[0],O[1])}return Promise.resolve(g.withIsolationScope(function(){try{return Promise.resolve(g.continueTrace({sentryTrace:P,baggage:q},function(){try{var o,d;return Promise.resolve(g.startSpan({name:"rpc request",op:"rpc.server",attributes:{ip:M,transport:"http",ua:null!=(o=c.headers.get("user-agent"))?o:"",origin:null!=(d=c.headers.get("origin"))?d:""}},function(){try{try{var o,d=[],f=t.generateCustomId("req_"),h=n.memo(function(){var e;return u.parse(null!=(e=c.headers.get("cookie"))?e:"")}),p={url:c.url,headers:c.headers,query:b.searchParams,body:j,rawBody:j,ip:M,requestId:f,getCookies:function(){return h()},getCookie:function(e){return h()[e]},setCookie:function(e,r,t){var n=u.serialize(e,r,t);_.append("Set-Cookie",n)},beforeSend:function(e){d.push(e)},sharedMiddlewareMemo:new Map,appendHeaders:function(e){for(var r=0,t=Object.entries(e);r<t.length;r++){var n=t[r],o=n[0],a=n[1];if(Array.isArray(a))for(var i,s=l(a);!(i=s()).done;)_.append(o,i.value);else _.append(o,a)}}};return g.getCurrentScope().setContext("rpc.request",{url:c.url,query:Object.fromEntries(b.searchParams.entries())}),g.getCurrentScope().addAttachment({filename:"rpc.request.body.json",data:j,contentType:"application/json"}),Promise.resolve(r.provideExecutionContext(r.createExecutionContext({type:"request",contextId:f,ip:null!=M?M:"0.0.0.0",userAgent:null!=(o=c.headers.get("user-agent"))?o:""}),function(){try{var r=new Map,n={body:{__typename:"rpc.response",calls:[]},status:200},o=b.pathname.split("/").filter(Boolean),u=o[o.length-1],c="$"==u[0];if(c){var h,v=u.slice(1),m=s.get(v);if(null==m)return Promise.resolve(new Response(JSON.stringify(e.notFoundError({entity:"handler"}).toResponse()),{status:404,headers:_}));var y=null!=(h=r.get(m))?h:[];y.push({id:t.generateCustomId("call_"),name:v,payload:j}),r.set(m,y)}else{var g=w.validate(j);if(!g.success)return Promise.resolve(new Response(JSON.stringify(e.validationError({errors:g.errors,entity:"request_data"}).toResponse()),{status:406,headers:_}));for(var P,S=l(g.value.calls);!(P=S()).done;){var q,M=P.value,x=s.get(M.name);if(null==x)return Promise.resolve(new Response(JSON.stringify(e.notFoundError({entity:"handler"}).toResponse()),{status:404,headers:_}));var E=null!=(q=r.get(x))?q:[];E.push(M),r.set(x,E)}}return Promise.resolve(Promise.all(Array.from(r.entries()).map(function(e){var r=e[0],t=e[1];try{return Promise.resolve(i[r].runMany(p,{requestId:f,calls:t})).then(function(e){var r;n.status=Math.max(n.status,e.status),(r=n.body.calls).push.apply(r,e.body.calls)})}catch(e){return Promise.reject(e)}}))).then(function(){return _.append("x-req-id",f),_.append("content-type","application/rpc+json"),_.append("x-powered-by","lowerdeck RPC"),Promise.resolve(Promise.all(d.map(function(e){return e()}))).then(function(){return new Response(a.serialize.encode(c?n.body.calls[0].result:n.body),{status:n.status,headers:_})})})}catch(e){return Promise.reject(e)}}))}catch(r){return console.error(r),g.captureException(r),Promise.resolve(new Response(JSON.stringify(e.internalServerError().toResponse()),{status:500,headers:_}))}}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}}))},v=null!=(d=c.headers.get("origin"))?d:"",m=!1;if(o.cors&&"domains"in o.cors)try{var y=new URL(v).hostname.split(".").slice(-2).join(".");m=o.cors.domains.includes(y)}catch(e){}else o.cors&&"check"in o.cors&&(m=o.cors.check(v));var b=new URL(c.url),P=null==(f=o.cors)||null==(f=f.headers)?void 0:f.join(", ");P&&(P=(", "+P).trim());var S=m?{"access-control-allow-origin":v,"access-control-allow-methods":"POST, OPTIONS","access-control-allow-headers":"Content-Type, Authorization, Baggage, Sentry-Trace"+(null!=P?P:""),"access-control-max-age":"604800","access-control-allow-credentials":"true"}:{};if("OPTIONS"==c.method)return Promise.resolve(m?new Response(null,{status:204,headers:S}):new Response(null,{status:403}));var j=null,q=function(e,r){try{var t=e()}catch(e){return r()}return t&&t.then?t.then(void 0,r):t}(function(){var e=a.serialize.decode;return Promise.resolve(c.text()).then(function(r){j=e.call(a.serialize,r)})},function(){var r=new Response(JSON.stringify(e.notAcceptableError({message:"Invalid JSON"}).toResponse()),{status:406});return h=1,r});return Promise.resolve(q&&q.then?q.then(p):p(q))}catch(e){return Promise.reject(e)}}}};
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/controller.ts","../src/rpcMux.ts","../src/server.ts","../src/extractIp.ts"],"sourcesContent":["import { ServiceError, validationError } from '@lowerdeck/error';\nimport { ValidationType } from '@lowerdeck/validation';\nimport * as Cookie from 'cookie';\n\nexport type Method = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\nexport interface ServiceRequest {\n query: URLSearchParams;\n headers: Headers;\n url: string;\n ip?: string;\n body: any;\n rawBody: any;\n requestId: string;\n\n getCookies: () => Record<string, string | undefined>;\n getCookie: (name: string) => string | undefined;\n setCookie: (name: string, value: string, opts?: Cookie.SerializeOptions) => void;\n\n sharedMiddlewareMemo: Map<string, Promise<any>>;\n beforeSend: (handler: () => Promise<any>) => void;\n appendHeaders: (headers: Record<string, string | string[]>) => void;\n}\n\nexport type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};\nexport type ExtendContext<C extends object, E> = E extends object ? Simplify<C & E> : C;\n\nexport class Group<Context extends { [key: string]: any } = {}> {\n constructor(\n private _middleware: Array<(ctx: Context & ServiceRequest) => Promise<any>> = []\n ) {}\n\n use<T extends { [key: string]: any } | undefined | void>(\n handler: (ctx: Context & ServiceRequest) => Promise<T>,\n opts?: {\n getSharedMemoKey?: (ctx: Context & ServiceRequest) => string;\n }\n ) {\n let middleware = async (ctx: Parameters<typeof handler>[0]): Promise<T> => {\n let key = opts?.getSharedMemoKey?.(ctx);\n if (key && ctx.sharedMiddlewareMemo.has(key)) {\n return await ctx.sharedMiddlewareMemo.get(key)!;\n }\n\n let res = handler(ctx);\n if (key) ctx.sharedMiddlewareMemo.set(key, res);\n\n return await res;\n };\n\n return new Group<Simplify<Context & T>>([...this._middleware, middleware]);\n }\n\n createMiddleware<T extends { [key: string]: any }, P = void>(\n handler: (ctx: Context & ServiceRequest, input: P) => Promise<T>,\n opts?: {\n getSharedMemoKey?: (ctx: Context & ServiceRequest, input: P) => string;\n }\n ) {\n return (input: P) =>\n async (ctx: Context & ServiceRequest): Promise<T> => {\n let key = opts?.getSharedMemoKey?.(ctx, input);\n if (key && ctx.sharedMiddlewareMemo.has(key)) {\n return await ctx.sharedMiddlewareMemo.get(key)!;\n }\n\n let res = handler(ctx, input);\n if (key) ctx.sharedMiddlewareMemo.set(key, res);\n\n return await res;\n };\n }\n\n handler() {\n return new Handler([...this._middleware]);\n }\n\n controller<\n HandlersAndSubControllers extends {\n [key: string]: Handler<any, any, any> | Controller<any>;\n }\n >(handlers: HandlersAndSubControllers): Controller<HandlersAndSubControllers> {\n return handlers;\n }\n}\n\nexport type Controller<\n HandlersAndSubControllers extends { [key: string]: Handler<any, any, any> | Controller<any> }\n> = HandlersAndSubControllers;\n\nexport type InferControllerType<T> = T extends Controller<infer U> ? U : never;\n\nexport type InferClient<\n HandlersAndSubControllers extends { [key: string]: Handler<any, any, any> | Controller<any> }\n> = {\n [K in keyof HandlersAndSubControllers]: HandlersAndSubControllers[K] extends Handler<\n infer I,\n infer O,\n infer C\n >\n ? ((\n input: I,\n opts?: { headers?: Record<string, string>; query?: Record<string, string> }\n ) => Promise<O>) & {\n getFull: (\n input: I,\n opts?: { headers?: Record<string, string>; query?: Record<string, string> }\n ) => Promise<{\n data: O;\n status: number;\n headers: Record<string, string>;\n }>;\n }\n : HandlersAndSubControllers[K] extends Controller<infer U>\n ? InferClient<U>\n : never;\n};\n\nexport class Handler<Input, Output, Context extends { [key: string]: any } = {}> {\n private _handler!: (\n ctx: Context & Omit<ServiceRequest, 'body'> & { input: Input }\n ) => Promise<Output>;\n private _validation: ValidationType<Input> | undefined;\n\n constructor(\n private _middleware: Array<(ctx: Context & ServiceRequest) => Promise<any>> = []\n ) {}\n\n do<HandlerOutput>(\n handler: (\n ctx: Context & Omit<ServiceRequest, 'body'> & { input: Input }\n ) => Promise<HandlerOutput>\n ) {\n if (this._handler != undefined) throw new Error('Handler already defined');\n\n // @ts-ignore\n this._handler = handler;\n\n return this as any as Handler<Input, HandlerOutput, Context>;\n }\n\n use<T extends { [key: string]: any } = {}>(\n handler: (ctx: Context & ServiceRequest) => Promise<T | undefined | void>\n ) {\n this._middleware.push(handler);\n return this as any as Handler<Input, Output, ExtendContext<Context, T>>;\n }\n\n input<HandlerInput>(validation: ValidationType<HandlerInput>) {\n if (this._validation != undefined) throw new Error('Input validation already defined');\n\n // @ts-ignore\n this._validation = validation;\n\n return this as any as Handler<HandlerInput, Output, Context>;\n }\n\n async run(\n req: ServiceRequest,\n initialContext: any\n ): Promise<{\n response: Output;\n }> {\n if (!this._handler) throw new Error('Handler not defined');\n\n let input = req.body as Input;\n\n if (this._validation) {\n let valRes = this._validation.validate(req.body);\n\n if (!valRes.success) {\n throw new ServiceError(\n validationError({ errors: valRes.errors, entity: 'call_data' })\n );\n }\n\n input = valRes.value;\n }\n\n let ctx = {\n ...initialContext,\n ...req,\n\n // Always use the sanitized input\n body: input\n };\n\n for (let mw of this._middleware) {\n let res = await mw(ctx);\n if (res) ctx = { ...ctx, ...res };\n }\n\n let res = await this._handler({\n ...ctx,\n input,\n body: undefined\n });\n\n return {\n response: res\n };\n }\n}\n","import {\n internalServerError,\n notAcceptableError,\n notFoundError,\n validationError\n} from '@lowerdeck/error';\nimport { createExecutionContext, provideExecutionContext } from '@lowerdeck/execution-context';\nimport { generateCustomId } from '@lowerdeck/id';\nimport { memo } from '@lowerdeck/memo';\nimport { getSentry } from '@lowerdeck/sentry';\nimport { serialize } from '@lowerdeck/serialize';\nimport { v } from '@lowerdeck/validation';\nimport * as Cookie from 'cookie';\nimport { ServiceRequest } from './controller';\nimport { parseForwardedFor } from './extractIp';\n\nlet Sentry = getSentry();\n\nlet validation = v.object({\n calls: v.array(\n v.object({\n id: v.string(),\n name: v.string(),\n payload: v.any()\n })\n )\n});\n\nexport let rpcMux = (\n opts: {\n path: string;\n cors?: {\n headers?: string[];\n } & ({ domains: string[] } | { check: (origin: string) => boolean });\n },\n rpcs: {\n handlerNames: string[];\n runMany: (\n req: ServiceRequest,\n body: {\n requestId: string;\n calls: {\n id: string;\n name: string;\n payload: any;\n }[];\n }\n ) => Promise<{\n status: number;\n body: {\n calls: any[];\n };\n }>;\n }[]\n) => {\n let handlerNameToRpcMap = new Map<string, number>(\n rpcs.flatMap((rpc, i) => rpc.handlerNames.map(name => [name, i]))\n );\n\n return {\n path: opts.path,\n\n fetch: async (req: any): Promise<any> => {\n let origin = req.headers.get('origin') ?? '';\n let corsOk = false;\n\n if (opts.cors && 'domains' in opts.cors) {\n try {\n let url = new URL(origin);\n let rootDomain = url.hostname.split('.').slice(-2).join('.');\n corsOk = opts.cors.domains.includes(rootDomain);\n } catch (e) {\n // Ignore -> no cors\n }\n } else if (opts.cors && 'check' in opts.cors) {\n corsOk = opts.cors.check(origin);\n }\n\n let url = new URL(req.url);\n\n let additionalCorsHeaders = opts.cors?.headers?.join(', ');\n if (additionalCorsHeaders) additionalCorsHeaders = `, ${additionalCorsHeaders}`.trim();\n\n let corsHeaders: Record<string, string> = corsOk\n ? {\n 'access-control-allow-origin': origin,\n 'access-control-allow-methods': 'POST, OPTIONS',\n 'access-control-allow-headers': `Content-Type, Authorization, Baggage, Sentry-Trace${\n additionalCorsHeaders ?? ''\n }`,\n 'access-control-max-age': '604800',\n 'access-control-allow-credentials': 'true'\n }\n : {};\n\n if (req.method == 'OPTIONS') {\n if (corsOk) {\n return new Response(null, {\n status: 204,\n headers: corsHeaders\n });\n }\n\n return new Response(null, { status: 403 });\n }\n\n let body: any = null;\n\n try {\n body = serialize.decode(await req.text());\n } catch (e) {\n return new Response(\n JSON.stringify(notAcceptableError({ message: 'Invalid JSON' }).toResponse()),\n { status: 406 }\n );\n }\n\n let sentryTraceHeaders = req.headers.get('sentry-trace');\n let sentryTrace =\n (Array.isArray(sentryTraceHeaders)\n ? sentryTraceHeaders.join(',')\n : sentryTraceHeaders) ?? undefined;\n let baggage = req.headers.get('baggage');\n\n let ip = parseForwardedFor(\n req.headers.get('lowerdeck-connecting-ip') ??\n req.headers.get('cf-connecting-ip') ??\n req.headers.get('x-forwarded-for') ??\n req.headers.get('x-real-ip')\n );\n\n let headers = new Headers();\n\n if (corsOk) {\n for (let [key, value] of Object.entries(corsHeaders)) {\n headers.append(key, value);\n }\n }\n\n return await Sentry.withIsolationScope(\n async () =>\n await Sentry.continueTrace(\n { sentryTrace, baggage },\n async () =>\n await Sentry.startSpan(\n {\n name: 'rpc request',\n op: 'rpc.server',\n attributes: {\n ip,\n transport: 'http',\n ua: req.headers.get('user-agent') ?? '',\n origin: req.headers.get('origin') ?? ''\n }\n },\n async () => {\n try {\n let beforeSends: Array<() => Promise<any>> = [];\n let id = generateCustomId('req_');\n\n let parseCookies = memo(() =>\n Cookie.parse(req.headers.get('cookie') ?? '')\n );\n\n let request: ServiceRequest = {\n url: req.url,\n headers: req.headers,\n query: url.searchParams,\n body,\n rawBody: body,\n ip,\n requestId: id,\n\n getCookies: () => parseCookies(),\n getCookie: (name: string) => parseCookies()[name],\n setCookie: (name: string, value: string, opts?: any) => {\n let cookie = Cookie.serialize(name, value, opts);\n // @ts-ignore\n headers.append('Set-Cookie', cookie);\n },\n\n beforeSend: (handler: () => Promise<any>) => {\n beforeSends.push(handler);\n },\n\n sharedMiddlewareMemo: new Map<string, Promise<any>>(),\n\n appendHeaders: (newHeaders: Record<string, string | string[]>) => {\n for (let [key, value] of Object.entries(newHeaders)) {\n if (Array.isArray(value)) {\n for (let v of value) headers.append(key, v);\n } else {\n headers.append(key, value);\n }\n }\n }\n };\n\n Sentry.getCurrentScope().setContext('rpc.request', {\n url: req.url,\n query: Object.fromEntries(url.searchParams.entries())\n });\n\n Sentry.getCurrentScope().addAttachment({\n filename: 'rpc.request.body.json',\n data: body,\n contentType: 'application/json'\n });\n\n return provideExecutionContext(\n createExecutionContext({\n type: 'request',\n contextId: id,\n ip: ip ?? '0.0.0.0',\n userAgent: req.headers.get('user-agent') ?? ''\n }),\n async () => {\n let callsByRpc = new Map<\n number,\n { id: string; name: string; payload: any }[]\n >();\n\n let resRef = {\n body: {\n __typename: 'rpc.response',\n calls: [] as any[]\n },\n status: 200\n };\n\n let pathParts = url.pathname.split('/').filter(Boolean);\n let lastPart = pathParts[pathParts.length - 1];\n\n if (lastPart[0] == '$') {\n let id = lastPart.slice(1);\n let rpcIndex = handlerNameToRpcMap.get(id);\n if (rpcIndex == undefined) {\n return new Response(\n JSON.stringify(\n notFoundError({ entity: 'handler' }).toResponse()\n ),\n { status: 404, headers }\n );\n }\n\n let calls = callsByRpc.get(rpcIndex) ?? [];\n calls.push({\n id: generateCustomId('call_'),\n name: id,\n payload: body\n });\n callsByRpc.set(rpcIndex, calls);\n } else {\n let valRes = validation.validate(body);\n if (!valRes.success) {\n return new Response(\n JSON.stringify(\n validationError({\n errors: valRes.errors,\n entity: 'request_data'\n }).toResponse()\n ),\n { status: 406, headers }\n );\n }\n\n for (let call of valRes.value.calls) {\n let rpcIndex = handlerNameToRpcMap.get(call.name);\n if (rpcIndex == undefined) {\n return new Response(\n JSON.stringify(\n notFoundError({ entity: 'handler' }).toResponse()\n ),\n { status: 404, headers }\n );\n }\n\n let calls = callsByRpc.get(rpcIndex) ?? [];\n calls.push(call as any);\n callsByRpc.set(rpcIndex, calls);\n }\n }\n\n await Promise.all(\n Array.from(callsByRpc.entries()).map(async ([rpcIndex, calls]) => {\n let rpc = rpcs[rpcIndex];\n let res = await rpc.runMany(request, {\n requestId: id,\n calls\n });\n\n resRef.status = Math.max(resRef.status, res.status);\n resRef.body.calls.push(...res.body.calls);\n })\n );\n\n headers.append('x-req-id', id);\n headers.append('content-type', 'application/rpc+json');\n headers.append('x-powered-by', 'lowerdeck RPC');\n\n await Promise.all(beforeSends.map(s => s()));\n\n return new Response(serialize.encode(resRef.body), {\n status: resRef.status,\n headers\n });\n }\n );\n } catch (e) {\n console.error(e);\n\n Sentry.captureException(e);\n\n return new Response(JSON.stringify(internalServerError().toResponse()), {\n status: 500,\n headers\n });\n }\n }\n )\n )\n );\n }\n };\n};\n","import { internalServerError, isServiceError, notFoundError } from '@lowerdeck/error';\nimport { getSentry } from '@lowerdeck/sentry';\nimport { Controller, Handler, ServiceRequest } from './controller';\n\nlet Sentry = getSentry();\n\nexport let createServer =\n (opts: {\n onError?: (opts: {\n request: ServiceRequest;\n error: any;\n reqId: string;\n callId: string;\n callName: string;\n }) => void;\n onRequest?: (opts: {\n reqId: string;\n callId: string;\n callName: string;\n request: ServiceRequest;\n response: { status: number; body: any };\n }) => void;\n }) =>\n (controller: Controller<any>) => {\n let findHandler = (name: string): Handler<any, any, any> | null => {\n let parts = name.split(':');\n let current = controller;\n\n while (current && parts.length > 0) {\n current = current[parts.shift()!];\n if (!current) return null;\n }\n\n if (current && current instanceof Handler) return current;\n\n return null;\n };\n\n let getSupportedHandlerNames = (controller: Controller<any>): string[] =>\n Object.entries(controller).flatMap(([key, value]) => {\n if (value instanceof Handler) return [key];\n if (typeof value == 'object')\n return getSupportedHandlerNames(value).map(name => `${key}:${name}`);\n return [];\n });\n\n let handlerNames = getSupportedHandlerNames(controller);\n\n let run = async (\n req: ServiceRequest,\n call: { id: string; name: string; payload: any },\n reqId: string\n ): Promise<{\n response: any;\n status: number;\n request: ServiceRequest;\n }> => {\n let request = { ...req, body: call.payload };\n\n try {\n let handler = findHandler(call.name);\n\n if (!handler) {\n return {\n request,\n status: 404,\n response: notFoundError({ entity: 'handler' }).toResponse()\n };\n }\n\n let response = await handler.run(request, {});\n\n return {\n status: 200,\n request: req,\n response: response.response\n };\n } catch (e) {\n console.error(e);\n\n if (isServiceError(e)) {\n if (e.data.status >= 500) {\n Sentry.captureException(e, {\n tags: { reqId }\n });\n }\n\n return {\n request,\n status: e.data.status,\n response: e.toResponse()\n };\n }\n\n Sentry.captureException(e, {\n tags: { reqId }\n });\n\n opts.onError?.({\n callName: call.name,\n callId: call.id,\n request: req,\n error: e,\n reqId\n });\n\n return {\n request,\n status: 500,\n response: internalServerError().toResponse()\n };\n }\n };\n\n let runMany = async (\n req: ServiceRequest,\n body: {\n calls: {\n id: string;\n name: string;\n payload: any;\n }[];\n requestId: string;\n }\n ): Promise<{\n status: number;\n body: any;\n }> => {\n let callRes = await Promise.all(\n body.calls.map(async (call, i) => {\n let res = await run(req, call as any, body.requestId);\n\n try {\n opts.onRequest?.({\n reqId: body.requestId,\n callId: call.id,\n callName: call.name,\n request: res.request,\n response: { status: res.status, body: res.response }\n });\n } catch (e) {\n Sentry.captureException(e);\n console.error(e);\n }\n\n return {\n __typename: 'rpc.response.call',\n id: call.id,\n name: call.name,\n status: res.status,\n result: res.response\n };\n })\n );\n\n return {\n status: Math.max(...callRes.map(c => c.status)),\n body: {\n __typename: 'rpc.response',\n calls: callRes\n }\n };\n };\n\n return {\n handlerNames,\n runMany\n\n // fetch,\n\n // http: async (\n // req: IncomingMessage & {\n // body: any;\n // },\n // res: ServerResponse & { send: (body: any) => void }\n // ) => {\n // let headers = new Headers(\n // Object.fromEntries(\n // Object.entries(req.headers).map(([key, value]) => [\n // key,\n // value === undefined ? '' : String(value)\n // ])\n // )\n // );\n // let url = new URL(req.url ?? '', `http://${req.headers.host}`);\n\n // let request = new Request(url.toString(), {\n // method: req.method,\n // headers,\n // body: JSON.stringify(req.body)\n // });\n\n // let response = await fetch(request);\n\n // res.statusCode = response.status;\n\n // for (let [key, value] of response.headers.entries()) {\n // res.setHeader(key, value);\n // }\n\n // res.send(response.body);\n // }\n };\n };\n","export let parseForwardedFor = (xForwardedForHeader?: string | null | undefined) => {\n if (typeof xForwardedForHeader != 'string') return undefined;\n\n let ips = xForwardedForHeader\n .split(',')\n .map(ip => ip.trim())\n .filter(Boolean);\n return ips.length > 0 ? ips[0] : undefined;\n};\n"],"names":["_settle","pact","state","value","s","_Pact","o","bind","v","then","observer","prototype","onFulfilled","onRejected","result","this","callback","e","_this","_isSettledPact","thenable","Group","_middleware","_proto","use","handler","opts","concat","ctx","_exit","_temp2","_result","res","key","sharedMiddlewareMemo","set","Promise","resolve","getSharedMemoKey","_temp","has","get","_await$ctx$sharedMidd","reject","createMiddleware","input","_exit2","_temp4","_result2","_temp3","_await$ctx$sharedMidd2","Handler","controller","handlers","_handler","_validation","_proto2","undefined","Error","push","validation","run","req","initialContext","_temp6","_extends","body","response","valRes","validate","success","ServiceError","validationError","errors","entity","_temp5","_forOf","mw","Sentry","getSentry","object","calls","array","id","string","name","payload","any","getSupportedHandlerNames","Object","entries","flatMap","_ref","map","handlerNames","runMany","all","call","i","reqId","request","parts","split","current","length","shift","findHandler","status","notFoundError","toResponse","_catch","console","error","isServiceError","data","captureException","tags","onError","callName","callId","internalServerError","requestId","onRequest","__typename","callRes","Math","max","apply","c","rpcs","handlerNameToRpcMap","Map","rpc","path","fetch","_req$headers$get6","_opts$cors","_ref2","_ref3","_req$headers$get","sentryTraceHeaders","headers","sentryTrace","Array","isArray","join","baggage","ip","xForwardedForHeader","ips","trim","filter","Boolean","parseForwardedFor","Headers","corsOk","_i","_Object$entries","corsHeaders","_Object$entries$_i","append","withIsolationScope","continueTrace","_req$headers$get2","_req$headers$get3","startSpan","op","attributes","transport","ua","origin","_req$headers$get5","beforeSends","generateCustomId","parseCookies","memo","_req$headers$get4","Cookie","parse","url","query","searchParams","rawBody","getCookies","getCookie","setCookie","cookie","serialize","beforeSend","appendHeaders","newHeaders","_i2","_Object$entries2","_Object$entries2$_i","_step","_iterator","_createForOfIteratorHelperLoose","done","getCurrentScope","setContext","fromEntries","addAttachment","filename","contentType","provideExecutionContext","createExecutionContext","type","contextId","userAgent","callsByRpc","resRef","pathParts","pathname","lastPart","_callsByRpc$get","slice","rpcIndex","Response","JSON","stringify","_iterator2","_step2","_callsByRpc$get2","from","_ref4","_resRef$body$calls","encode","cors","rootDomain","URL","hostname","domains","includes","check","additionalCorsHeaders","method","_decode","decode","text","_req$text","_Response","notAcceptableError","message"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/controller.ts","../src/rpcMux.ts","../src/server.ts","../src/extractIp.ts"],"sourcesContent":["import { ServiceError, validationError } from '@lowerdeck/error';\nimport { ValidationType } from '@lowerdeck/validation';\nimport * as Cookie from 'cookie';\n\nexport type Method = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\nexport interface ServiceRequest {\n query: URLSearchParams;\n headers: Headers;\n url: string;\n ip?: string;\n body: any;\n rawBody: any;\n requestId: string;\n\n getCookies: () => Record<string, string | undefined>;\n getCookie: (name: string) => string | undefined;\n setCookie: (name: string, value: string, opts?: Cookie.SerializeOptions) => void;\n\n sharedMiddlewareMemo: Map<string, Promise<any>>;\n beforeSend: (handler: () => Promise<any>) => void;\n appendHeaders: (headers: Record<string, string | string[]>) => void;\n}\n\nexport type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};\nexport type ExtendContext<C extends object, E> = E extends object ? Simplify<C & E> : C;\n\nexport class Group<Context extends { [key: string]: any } = {}> {\n constructor(\n private _middleware: Array<(ctx: Context & ServiceRequest) => Promise<any>> = []\n ) {}\n\n use<T extends { [key: string]: any } | undefined | void>(\n handler: (ctx: Context & ServiceRequest) => Promise<T>,\n opts?: {\n getSharedMemoKey?: (ctx: Context & ServiceRequest) => string;\n }\n ) {\n let middleware = async (ctx: Parameters<typeof handler>[0]): Promise<T> => {\n let key = opts?.getSharedMemoKey?.(ctx);\n if (key && ctx.sharedMiddlewareMemo.has(key)) {\n return await ctx.sharedMiddlewareMemo.get(key)!;\n }\n\n let res = handler(ctx);\n if (key) ctx.sharedMiddlewareMemo.set(key, res);\n\n return await res;\n };\n\n return new Group<Simplify<Context & T>>([...this._middleware, middleware]);\n }\n\n createMiddleware<T extends { [key: string]: any }, P = void>(\n handler: (ctx: Context & ServiceRequest, input: P) => Promise<T>,\n opts?: {\n getSharedMemoKey?: (ctx: Context & ServiceRequest, input: P) => string;\n }\n ) {\n return (input: P) =>\n async (ctx: Context & ServiceRequest): Promise<T> => {\n let key = opts?.getSharedMemoKey?.(ctx, input);\n if (key && ctx.sharedMiddlewareMemo.has(key)) {\n return await ctx.sharedMiddlewareMemo.get(key)!;\n }\n\n let res = handler(ctx, input);\n if (key) ctx.sharedMiddlewareMemo.set(key, res);\n\n return await res;\n };\n }\n\n handler() {\n return new Handler([...this._middleware]);\n }\n\n controller<\n HandlersAndSubControllers extends {\n [key: string]: Handler<any, any, any> | Controller<any>;\n }\n >(handlers: HandlersAndSubControllers): Controller<HandlersAndSubControllers> {\n return handlers;\n }\n}\n\nexport type Controller<\n HandlersAndSubControllers extends { [key: string]: Handler<any, any, any> | Controller<any> }\n> = HandlersAndSubControllers;\n\nexport type InferControllerType<T> = T extends Controller<infer U> ? U : never;\n\nexport type InferClient<\n HandlersAndSubControllers extends { [key: string]: Handler<any, any, any> | Controller<any> }\n> = {\n [K in keyof HandlersAndSubControllers]: HandlersAndSubControllers[K] extends Handler<\n infer I,\n infer O,\n infer C\n >\n ? ((\n input: I,\n opts?: { headers?: Record<string, string>; query?: Record<string, string> }\n ) => Promise<O>) & {\n getFull: (\n input: I,\n opts?: { headers?: Record<string, string>; query?: Record<string, string> }\n ) => Promise<{\n data: O;\n status: number;\n headers: Record<string, string>;\n }>;\n }\n : HandlersAndSubControllers[K] extends Controller<infer U>\n ? InferClient<U>\n : never;\n};\n\nexport class Handler<Input, Output, Context extends { [key: string]: any } = {}> {\n private _handler!: (\n ctx: Context & Omit<ServiceRequest, 'body'> & { input: Input }\n ) => Promise<Output>;\n private _validation: ValidationType<Input> | undefined;\n\n constructor(\n private _middleware: Array<(ctx: Context & ServiceRequest) => Promise<any>> = []\n ) {}\n\n do<HandlerOutput>(\n handler: (\n ctx: Context & Omit<ServiceRequest, 'body'> & { input: Input }\n ) => Promise<HandlerOutput>\n ) {\n if (this._handler != undefined) throw new Error('Handler already defined');\n\n // @ts-ignore\n this._handler = handler;\n\n return this as any as Handler<Input, HandlerOutput, Context>;\n }\n\n use<T extends { [key: string]: any } = {}>(\n handler: (ctx: Context & ServiceRequest) => Promise<T | undefined | void>\n ) {\n this._middleware.push(handler);\n return this as any as Handler<Input, Output, ExtendContext<Context, T>>;\n }\n\n input<HandlerInput>(validation: ValidationType<HandlerInput>) {\n if (this._validation != undefined) throw new Error('Input validation already defined');\n\n // @ts-ignore\n this._validation = validation;\n\n return this as any as Handler<HandlerInput, Output, Context>;\n }\n\n async run(\n req: ServiceRequest,\n initialContext: any\n ): Promise<{\n response: Output;\n }> {\n if (!this._handler) throw new Error('Handler not defined');\n\n let input = req.body as Input;\n\n if (this._validation) {\n let valRes = this._validation.validate(req.body);\n\n if (!valRes.success) {\n throw new ServiceError(\n validationError({ errors: valRes.errors, entity: 'call_data' })\n );\n }\n\n input = valRes.value;\n }\n\n let ctx = {\n ...initialContext,\n ...req,\n\n // Always use the sanitized input\n body: input\n };\n\n for (let mw of this._middleware) {\n let res = await mw(ctx);\n if (res) ctx = { ...ctx, ...res };\n }\n\n let res = await this._handler({\n ...ctx,\n input,\n body: undefined\n });\n\n return {\n response: res\n };\n }\n}\n","import {\n internalServerError,\n notAcceptableError,\n notFoundError,\n validationError\n} from '@lowerdeck/error';\nimport { createExecutionContext, provideExecutionContext } from '@lowerdeck/execution-context';\nimport { generateCustomId } from '@lowerdeck/id';\nimport { memo } from '@lowerdeck/memo';\nimport { getSentry } from '@lowerdeck/sentry';\nimport { serialize } from '@lowerdeck/serialize';\nimport { v } from '@lowerdeck/validation';\nimport * as Cookie from 'cookie';\nimport { ServiceRequest } from './controller';\nimport { parseForwardedFor } from './extractIp';\n\nlet Sentry = getSentry();\n\nlet validation = v.object({\n calls: v.array(\n v.object({\n id: v.string(),\n name: v.string(),\n payload: v.any()\n })\n )\n});\n\nexport let rpcMux = (\n opts: {\n path: string;\n cors?: {\n headers?: string[];\n } & ({ domains: string[] } | { check: (origin: string) => boolean });\n },\n rpcs: {\n handlerNames: string[];\n runMany: (\n req: ServiceRequest,\n body: {\n requestId: string;\n calls: {\n id: string;\n name: string;\n payload: any;\n }[];\n }\n ) => Promise<{\n status: number;\n body: {\n calls: any[];\n };\n }>;\n }[]\n) => {\n let handlerNameToRpcMap = new Map<string, number>(\n rpcs.flatMap((rpc, i) => rpc.handlerNames.map(name => [name, i]))\n );\n\n return {\n path: opts.path,\n\n fetch: async (req: any): Promise<any> => {\n let origin = req.headers.get('origin') ?? '';\n let corsOk = false;\n\n if (opts.cors && 'domains' in opts.cors) {\n try {\n let url = new URL(origin);\n let rootDomain = url.hostname.split('.').slice(-2).join('.');\n corsOk = opts.cors.domains.includes(rootDomain);\n } catch (e) {\n // Ignore -> no cors\n }\n } else if (opts.cors && 'check' in opts.cors) {\n corsOk = opts.cors.check(origin);\n }\n\n let url = new URL(req.url);\n\n let additionalCorsHeaders = opts.cors?.headers?.join(', ');\n if (additionalCorsHeaders) additionalCorsHeaders = `, ${additionalCorsHeaders}`.trim();\n\n let corsHeaders: Record<string, string> = corsOk\n ? {\n 'access-control-allow-origin': origin,\n 'access-control-allow-methods': 'POST, OPTIONS',\n 'access-control-allow-headers': `Content-Type, Authorization, Baggage, Sentry-Trace${\n additionalCorsHeaders ?? ''\n }`,\n 'access-control-max-age': '604800',\n 'access-control-allow-credentials': 'true'\n }\n : {};\n\n if (req.method == 'OPTIONS') {\n if (corsOk) {\n return new Response(null, {\n status: 204,\n headers: corsHeaders\n });\n }\n\n return new Response(null, { status: 403 });\n }\n\n let body: any = null;\n\n try {\n body = serialize.decode(await req.text());\n } catch (e) {\n return new Response(\n JSON.stringify(notAcceptableError({ message: 'Invalid JSON' }).toResponse()),\n { status: 406 }\n );\n }\n\n let sentryTraceHeaders = req.headers.get('sentry-trace');\n let sentryTrace =\n (Array.isArray(sentryTraceHeaders)\n ? sentryTraceHeaders.join(',')\n : sentryTraceHeaders) ?? undefined;\n let baggage = req.headers.get('baggage');\n\n let ip = parseForwardedFor(\n req.headers.get('lowerdeck-connecting-ip') ??\n req.headers.get('cf-connecting-ip') ??\n req.headers.get('x-forwarded-for') ??\n req.headers.get('x-real-ip')\n );\n\n let headers = new Headers();\n\n if (corsOk) {\n for (let [key, value] of Object.entries(corsHeaders)) {\n headers.append(key, value);\n }\n }\n\n return await Sentry.withIsolationScope(\n async () =>\n await Sentry.continueTrace(\n { sentryTrace, baggage },\n async () =>\n await Sentry.startSpan(\n {\n name: 'rpc request',\n op: 'rpc.server',\n attributes: {\n ip,\n transport: 'http',\n ua: req.headers.get('user-agent') ?? '',\n origin: req.headers.get('origin') ?? ''\n }\n },\n async () => {\n try {\n let beforeSends: Array<() => Promise<any>> = [];\n let id = generateCustomId('req_');\n\n let parseCookies = memo(() =>\n Cookie.parse(req.headers.get('cookie') ?? '')\n );\n\n let request: ServiceRequest = {\n url: req.url,\n headers: req.headers,\n query: url.searchParams,\n body,\n rawBody: body,\n ip,\n requestId: id,\n\n getCookies: () => parseCookies(),\n getCookie: (name: string) => parseCookies()[name],\n setCookie: (name: string, value: string, opts?: any) => {\n let cookie = Cookie.serialize(name, value, opts);\n // @ts-ignore\n headers.append('Set-Cookie', cookie);\n },\n\n beforeSend: (handler: () => Promise<any>) => {\n beforeSends.push(handler);\n },\n\n sharedMiddlewareMemo: new Map<string, Promise<any>>(),\n\n appendHeaders: (newHeaders: Record<string, string | string[]>) => {\n for (let [key, value] of Object.entries(newHeaders)) {\n if (Array.isArray(value)) {\n for (let v of value) headers.append(key, v);\n } else {\n headers.append(key, value);\n }\n }\n }\n };\n\n Sentry.getCurrentScope().setContext('rpc.request', {\n url: req.url,\n query: Object.fromEntries(url.searchParams.entries())\n });\n\n Sentry.getCurrentScope().addAttachment({\n filename: 'rpc.request.body.json',\n data: body,\n contentType: 'application/json'\n });\n\n return provideExecutionContext(\n createExecutionContext({\n type: 'request',\n contextId: id,\n ip: ip ?? '0.0.0.0',\n userAgent: req.headers.get('user-agent') ?? ''\n }),\n async () => {\n let callsByRpc = new Map<\n number,\n { id: string; name: string; payload: any }[]\n >();\n\n let resRef = {\n body: {\n __typename: 'rpc.response',\n calls: [] as any[]\n },\n status: 200\n };\n\n let pathParts = url.pathname.split('/').filter(Boolean);\n let lastPart = pathParts[pathParts.length - 1];\n\n let isSingle = lastPart[0] == '$';\n\n if (isSingle) {\n let id = lastPart.slice(1);\n let rpcIndex = handlerNameToRpcMap.get(id);\n if (rpcIndex == undefined) {\n return new Response(\n JSON.stringify(\n notFoundError({ entity: 'handler' }).toResponse()\n ),\n { status: 404, headers }\n );\n }\n\n let calls = callsByRpc.get(rpcIndex) ?? [];\n calls.push({\n id: generateCustomId('call_'),\n name: id,\n payload: body\n });\n callsByRpc.set(rpcIndex, calls);\n } else {\n let valRes = validation.validate(body);\n if (!valRes.success) {\n return new Response(\n JSON.stringify(\n validationError({\n errors: valRes.errors,\n entity: 'request_data'\n }).toResponse()\n ),\n { status: 406, headers }\n );\n }\n\n for (let call of valRes.value.calls) {\n let rpcIndex = handlerNameToRpcMap.get(call.name);\n if (rpcIndex == undefined) {\n return new Response(\n JSON.stringify(\n notFoundError({ entity: 'handler' }).toResponse()\n ),\n { status: 404, headers }\n );\n }\n\n let calls = callsByRpc.get(rpcIndex) ?? [];\n calls.push(call as any);\n callsByRpc.set(rpcIndex, calls);\n }\n }\n\n await Promise.all(\n Array.from(callsByRpc.entries()).map(async ([rpcIndex, calls]) => {\n let rpc = rpcs[rpcIndex];\n let res = await rpc.runMany(request, {\n requestId: id,\n calls\n });\n\n resRef.status = Math.max(resRef.status, res.status);\n resRef.body.calls.push(...res.body.calls);\n })\n );\n\n headers.append('x-req-id', id);\n headers.append('content-type', 'application/rpc+json');\n headers.append('x-powered-by', 'lowerdeck RPC');\n\n await Promise.all(beforeSends.map(s => s()));\n\n return new Response(\n serialize.encode(\n isSingle ? resRef.body.calls[0].result : resRef.body\n ),\n {\n status: resRef.status,\n headers\n }\n );\n }\n );\n } catch (e) {\n console.error(e);\n\n Sentry.captureException(e);\n\n return new Response(JSON.stringify(internalServerError().toResponse()), {\n status: 500,\n headers\n });\n }\n }\n )\n )\n );\n }\n };\n};\n","import { internalServerError, isServiceError, notFoundError } from '@lowerdeck/error';\nimport { getSentry } from '@lowerdeck/sentry';\nimport { Controller, Handler, ServiceRequest } from './controller';\n\nlet Sentry = getSentry();\n\nexport let createServer =\n (opts: {\n onError?: (opts: {\n request: ServiceRequest;\n error: any;\n reqId: string;\n callId: string;\n callName: string;\n }) => void;\n onRequest?: (opts: {\n reqId: string;\n callId: string;\n callName: string;\n request: ServiceRequest;\n response: { status: number; body: any };\n }) => void;\n }) =>\n (controller: Controller<any>) => {\n let findHandler = (name: string): Handler<any, any, any> | null => {\n let parts = name.split(':');\n let current = controller;\n\n while (current && parts.length > 0) {\n current = current[parts.shift()!];\n if (!current) return null;\n }\n\n if (current && current instanceof Handler) return current;\n\n return null;\n };\n\n let getSupportedHandlerNames = (controller: Controller<any>): string[] =>\n Object.entries(controller).flatMap(([key, value]) => {\n if (value instanceof Handler) return [key];\n if (typeof value == 'object')\n return getSupportedHandlerNames(value).map(name => `${key}:${name}`);\n return [];\n });\n\n let handlerNames = getSupportedHandlerNames(controller);\n\n let run = async (\n req: ServiceRequest,\n call: { id: string; name: string; payload: any },\n reqId: string\n ): Promise<{\n response: any;\n status: number;\n request: ServiceRequest;\n }> => {\n let request = { ...req, body: call.payload };\n\n try {\n let handler = findHandler(call.name);\n\n if (!handler) {\n return {\n request,\n status: 404,\n response: notFoundError({ entity: 'handler' }).toResponse()\n };\n }\n\n let response = await handler.run(request, {});\n\n return {\n status: 200,\n request: req,\n response: response.response\n };\n } catch (e) {\n console.error(e);\n\n if (isServiceError(e)) {\n if (e.data.status >= 500) {\n Sentry.captureException(e, {\n tags: { reqId }\n });\n }\n\n return {\n request,\n status: e.data.status,\n response: e.toResponse()\n };\n }\n\n Sentry.captureException(e, {\n tags: { reqId }\n });\n\n opts.onError?.({\n callName: call.name,\n callId: call.id,\n request: req,\n error: e,\n reqId\n });\n\n return {\n request,\n status: 500,\n response: internalServerError().toResponse()\n };\n }\n };\n\n let runMany = async (\n req: ServiceRequest,\n body: {\n calls: {\n id: string;\n name: string;\n payload: any;\n }[];\n requestId: string;\n }\n ): Promise<{\n status: number;\n body: any;\n }> => {\n let callRes = await Promise.all(\n body.calls.map(async (call, i) => {\n let res = await run(req, call as any, body.requestId);\n\n try {\n opts.onRequest?.({\n reqId: body.requestId,\n callId: call.id,\n callName: call.name,\n request: res.request,\n response: { status: res.status, body: res.response }\n });\n } catch (e) {\n Sentry.captureException(e);\n console.error(e);\n }\n\n return {\n __typename: 'rpc.response.call',\n id: call.id,\n name: call.name,\n status: res.status,\n result: res.response\n };\n })\n );\n\n return {\n status: Math.max(...callRes.map(c => c.status)),\n body: {\n __typename: 'rpc.response',\n calls: callRes\n }\n };\n };\n\n return {\n handlerNames,\n runMany\n\n // fetch,\n\n // http: async (\n // req: IncomingMessage & {\n // body: any;\n // },\n // res: ServerResponse & { send: (body: any) => void }\n // ) => {\n // let headers = new Headers(\n // Object.fromEntries(\n // Object.entries(req.headers).map(([key, value]) => [\n // key,\n // value === undefined ? '' : String(value)\n // ])\n // )\n // );\n // let url = new URL(req.url ?? '', `http://${req.headers.host}`);\n\n // let request = new Request(url.toString(), {\n // method: req.method,\n // headers,\n // body: JSON.stringify(req.body)\n // });\n\n // let response = await fetch(request);\n\n // res.statusCode = response.status;\n\n // for (let [key, value] of response.headers.entries()) {\n // res.setHeader(key, value);\n // }\n\n // res.send(response.body);\n // }\n };\n };\n","export let parseForwardedFor = (xForwardedForHeader?: string | null | undefined) => {\n if (typeof xForwardedForHeader != 'string') return undefined;\n\n let ips = xForwardedForHeader\n .split(',')\n .map(ip => ip.trim())\n .filter(Boolean);\n return ips.length > 0 ? ips[0] : undefined;\n};\n"],"names":["_settle","pact","state","value","s","_Pact","o","bind","v","then","observer","prototype","onFulfilled","onRejected","result","this","callback","e","_this","_isSettledPact","thenable","Group","_middleware","_proto","use","handler","opts","concat","ctx","_exit","_temp2","_result","res","key","sharedMiddlewareMemo","set","Promise","resolve","getSharedMemoKey","_temp","has","get","_await$ctx$sharedMidd","reject","createMiddleware","input","_exit2","_temp4","_result2","_temp3","_await$ctx$sharedMidd2","Handler","controller","handlers","_handler","_validation","_proto2","undefined","Error","push","validation","run","req","initialContext","_temp6","_extends","body","response","valRes","validate","success","ServiceError","validationError","errors","entity","_temp5","_forOf","mw","Sentry","getSentry","object","calls","array","id","string","name","payload","any","getSupportedHandlerNames","Object","entries","flatMap","_ref","map","handlerNames","runMany","all","call","i","reqId","request","parts","split","current","length","shift","findHandler","status","notFoundError","toResponse","_catch","console","error","isServiceError","data","captureException","tags","onError","callName","callId","internalServerError","requestId","onRequest","__typename","callRes","Math","max","apply","c","rpcs","handlerNameToRpcMap","Map","rpc","path","fetch","_req$headers$get6","_opts$cors","_ref2","_ref3","_req$headers$get","sentryTraceHeaders","headers","sentryTrace","Array","isArray","join","baggage","ip","xForwardedForHeader","ips","trim","filter","Boolean","parseForwardedFor","Headers","corsOk","_i","_Object$entries","corsHeaders","_Object$entries$_i","append","withIsolationScope","continueTrace","_req$headers$get2","_req$headers$get3","startSpan","op","attributes","transport","ua","origin","_req$headers$get5","beforeSends","generateCustomId","parseCookies","memo","_req$headers$get4","Cookie","parse","url","query","searchParams","rawBody","getCookies","getCookie","setCookie","cookie","serialize","beforeSend","appendHeaders","newHeaders","_i2","_Object$entries2","_Object$entries2$_i","_iterator","_step","_createForOfIteratorHelperLoose","done","getCurrentScope","setContext","fromEntries","addAttachment","filename","contentType","provideExecutionContext","createExecutionContext","type","contextId","userAgent","callsByRpc","resRef","pathParts","pathname","lastPart","isSingle","_callsByRpc$get","slice","rpcIndex","Response","JSON","stringify","_iterator2","_step2","_callsByRpc$get2","from","_ref4","_resRef$body$calls","encode","cors","rootDomain","URL","hostname","domains","includes","check","additionalCorsHeaders","method","_decode","decode","text","_req$text","_Response","notAcceptableError","message"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{ServiceError as e,validationError as r,notFoundError as t,internalServerError as n,notAcceptableError as o,isServiceError as a}from"@lowerdeck/error";import{provideExecutionContext as s,createExecutionContext as i}from"@lowerdeck/execution-context";import{generateCustomId as u}from"@lowerdeck/id";import{memo as l}from"@lowerdeck/memo";import{getSentry as c}from"@lowerdeck/sentry";import{serialize as d}from"@lowerdeck/serialize";import{v as f}from"@lowerdeck/validation";import*as h from"cookie";function p(e,r){(null==r||r>e.length)&&(r=e.length);for(var t=0,n=Array(r);t<r;t++)n[t]=e[t];return n}function m(e,r){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,r){if(e){if("string"==typeof e)return p(e,r);var t={}.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?p(e,r):void 0}}(e))||r&&e&&"number"==typeof e.length){t&&(e=t);var n=0;return function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function v(){return v=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)({}).hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e},v.apply(null,arguments)}const y="undefined"!=typeof Symbol?Symbol.iterator||(Symbol.iterator=Symbol("Symbol.iterator")):"@@iterator";function g(e,r,t){if(!e.s){if(t instanceof w){if(!t.s)return void(t.o=g.bind(null,e,r));1&r&&(r=t.s),t=t.v}if(t&&t.then)return void t.then(g.bind(null,e,r),g.bind(null,e,2));e.s=r,e.v=t;var n=e.o;n&&n(e)}}var w=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(r,t){var n=new e,o=this.s;if(o){var a=1&o?r:t;if(a){try{g(n,1,a(this.v))}catch(e){g(n,2,e)}return n}return this}return this.o=function(e){try{var o=e.v;1&e.s?g(n,1,r?r(o):o):t?g(n,1,t(o)):g(n,2,o)}catch(e){g(n,2,e)}},n},e}();function b(e){return e instanceof w&&1&e.s}var P=/*#__PURE__*/function(){function e(e){void 0===e&&(e=[]),this._middleware=void 0,this._middleware=e}var r=e.prototype;return r.use=function(r,t){return new e([].concat(this._middleware,[function(e){try{var n,o=function(t){if(n)return t;var o=r(e);return a&&e.sharedMiddlewareMemo.set(a,o),Promise.resolve(o)},a=null==t||null==t.getSharedMemoKey?void 0:t.getSharedMemoKey(e),s=function(){if(a&&e.sharedMiddlewareMemo.has(a))return Promise.resolve(e.sharedMiddlewareMemo.get(a)).then(function(e){return n=1,e})}();return Promise.resolve(s&&s.then?s.then(o):o(s))}catch(e){return Promise.reject(e)}}]))},r.createMiddleware=function(e,r){return function(t){return function(n){try{var o,a=function(r){if(o)return r;var a=e(n,t);return s&&n.sharedMiddlewareMemo.set(s,a),Promise.resolve(a)},s=null==r||null==r.getSharedMemoKey?void 0:r.getSharedMemoKey(n,t),i=function(){if(s&&n.sharedMiddlewareMemo.has(s))return Promise.resolve(n.sharedMiddlewareMemo.get(s)).then(function(e){return o=1,e})}();return Promise.resolve(i&&i.then?i.then(a):a(i))}catch(e){return Promise.reject(e)}}}},r.handler=function(){return new j([].concat(this._middleware))},r.controller=function(e){return e},e}(),j=/*#__PURE__*/function(){function t(e){void 0===e&&(e=[]),this._middleware=void 0,this._handler=void 0,this._validation=void 0,this._middleware=e}var n=t.prototype;return n.do=function(e){if(null!=this._handler)throw new Error("Handler already defined");return this._handler=e,this},n.use=function(e){return this._middleware.push(e),this},n.input=function(e){if(null!=this._validation)throw new Error("Input validation already defined");return this._validation=e,this},n.run=function(t,n){try{var o=function(){return Promise.resolve(a._handler(v({},u,{input:s,body:void 0}))).then(function(e){return{response:e}})},a=this;if(!a._handler)throw new Error("Handler not defined");var s=t.body;if(a._validation){var i=a._validation.validate(t.body);if(!i.success)throw new e(r({errors:i.errors,entity:"call_data"}));s=i.value}var u=v({},n,t,{body:s}),l=function(e,r){if("function"==typeof e[y]){var t,n,o,a=function(e){try{for(;!(t=s.next()).done;)if((e=r(t.value))&&e.then){if(!b(e))return void e.then(a,o||(o=g.bind(null,n=new w,2)));e=e.v}n?g(n,1,e):n=e}catch(e){g(n||(n=new w),2,e)}},s=e[y]();if(a(),s.return){var i=function(e){try{t.done||s.return()}catch(e){}return e};if(n&&n.then)return n.then(i,function(e){throw i(e)});i()}return n}if(!("length"in e))throw new TypeError("Object is not iterable");for(var u=[],l=0;l<e.length;l++)u.push(e[l]);return function(e,r){var t,n,o=-1;return function a(s){try{for(;++o<e.length;)if((s=r(o))&&s.then){if(!b(s))return void s.then(a,n||(n=g.bind(null,t=new w,2)));s=s.v}t?g(t,1,s):t=s}catch(e){g(t||(t=new w),2,e)}}(),t}(u,function(e){return r(u[e])})}(a._middleware,function(e){return Promise.resolve(e(u)).then(function(e){e&&(u=v({},u,e))})});return Promise.resolve(l&&l.then?l.then(o):o())}catch(e){return Promise.reject(e)}},t}(),M=c(),S=f.object({calls:f.array(f.object({id:f.string(),name:f.string(),payload:f.any()}))}),_=function(e,a){var c=new Map(a.flatMap(function(e,r){return e.handlerNames.map(function(e){return[e,r]})}));return{path:e.path,fetch:function(f){try{var p,v,y,g=function(e){var o,p,v,g;if(y)return e;var w=f.headers.get("sentry-trace"),P=null!=(o=Array.isArray(w)?w.join(","):w)?o:void 0,_=f.headers.get("baggage"),O=function(e){if("string"==typeof e){var r=e.split(",").map(function(e){return e.trim()}).filter(Boolean);return r.length>0?r[0]:void 0}}(null!=(p=null!=(v=null!=(g=f.headers.get("lowerdeck-connecting-ip"))?g:f.headers.get("cf-connecting-ip"))?v:f.headers.get("x-forwarded-for"))?p:f.headers.get("x-real-ip")),x=new Headers;if(b)for(var I=0,k=Object.entries(q);I<k.length;I++){var A=k[I];x.append(A[0],A[1])}return Promise.resolve(M.withIsolationScope(function(){try{return Promise.resolve(M.continueTrace({sentryTrace:P,baggage:_},function(){try{var e,o;return Promise.resolve(M.startSpan({name:"rpc request",op:"rpc.server",attributes:{ip:O,transport:"http",ua:null!=(e=f.headers.get("user-agent"))?e:"",origin:null!=(o=f.headers.get("origin"))?o:""}},function(){try{try{var e,o=[],p=u("req_"),v=l(function(){var e;return h.parse(null!=(e=f.headers.get("cookie"))?e:"")}),y={url:f.url,headers:f.headers,query:j.searchParams,body:R,rawBody:R,ip:O,requestId:p,getCookies:function(){return v()},getCookie:function(e){return v()[e]},setCookie:function(e,r,t){var n=h.serialize(e,r,t);x.append("Set-Cookie",n)},beforeSend:function(e){o.push(e)},sharedMiddlewareMemo:new Map,appendHeaders:function(e){for(var r=0,t=Object.entries(e);r<t.length;r++){var n=t[r],o=n[0],a=n[1];if(Array.isArray(a))for(var s,i=m(a);!(s=i()).done;)x.append(o,s.value);else x.append(o,a)}}};return M.getCurrentScope().setContext("rpc.request",{url:f.url,query:Object.fromEntries(j.searchParams.entries())}),M.getCurrentScope().addAttachment({filename:"rpc.request.body.json",data:R,contentType:"application/json"}),Promise.resolve(s(i({type:"request",contextId:p,ip:null!=O?O:"0.0.0.0",userAgent:null!=(e=f.headers.get("user-agent"))?e:""}),function(){try{var e=new Map,n={body:{__typename:"rpc.response",calls:[]},status:200},s=j.pathname.split("/").filter(Boolean),i=s[s.length-1];if("$"==i[0]){var l,f=i.slice(1),h=c.get(f);if(null==h)return Promise.resolve(new Response(JSON.stringify(t({entity:"handler"}).toResponse()),{status:404,headers:x}));var v=null!=(l=e.get(h))?l:[];v.push({id:u("call_"),name:f,payload:R}),e.set(h,v)}else{var g=S.validate(R);if(!g.success)return Promise.resolve(new Response(JSON.stringify(r({errors:g.errors,entity:"request_data"}).toResponse()),{status:406,headers:x}));for(var w,b=m(g.value.calls);!(w=b()).done;){var P,M=w.value,_=c.get(M.name);if(null==_)return Promise.resolve(new Response(JSON.stringify(t({entity:"handler"}).toResponse()),{status:404,headers:x}));var q=null!=(P=e.get(_))?P:[];q.push(M),e.set(_,q)}}return Promise.resolve(Promise.all(Array.from(e.entries()).map(function(e){var r=e[0],t=e[1];try{return Promise.resolve(a[r].runMany(y,{requestId:p,calls:t})).then(function(e){var r;n.status=Math.max(n.status,e.status),(r=n.body.calls).push.apply(r,e.body.calls)})}catch(e){return Promise.reject(e)}}))).then(function(){return x.append("x-req-id",p),x.append("content-type","application/rpc+json"),x.append("x-powered-by","lowerdeck RPC"),Promise.resolve(Promise.all(o.map(function(e){return e()}))).then(function(){return new Response(d.encode(n.body),{status:n.status,headers:x})})})}catch(e){return Promise.reject(e)}}))}catch(e){return console.error(e),M.captureException(e),Promise.resolve(new Response(JSON.stringify(n().toResponse()),{status:500,headers:x}))}}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}}))},w=null!=(p=f.headers.get("origin"))?p:"",b=!1;if(e.cors&&"domains"in e.cors)try{var P=new URL(w).hostname.split(".").slice(-2).join(".");b=e.cors.domains.includes(P)}catch(e){}else e.cors&&"check"in e.cors&&(b=e.cors.check(w));var j=new URL(f.url),_=null==(v=e.cors)||null==(v=v.headers)?void 0:v.join(", ");_&&(_=(", "+_).trim());var q=b?{"access-control-allow-origin":w,"access-control-allow-methods":"POST, OPTIONS","access-control-allow-headers":"Content-Type, Authorization, Baggage, Sentry-Trace"+(null!=_?_:""),"access-control-max-age":"604800","access-control-allow-credentials":"true"}:{};if("OPTIONS"==f.method)return Promise.resolve(b?new Response(null,{status:204,headers:q}):new Response(null,{status:403}));var R=null,O=function(e,r){try{var t=e()}catch(e){return r()}return t&&t.then?t.then(void 0,r):t}(function(){var e=d.decode;return Promise.resolve(f.text()).then(function(r){R=e.call(d,r)})},function(){var e=new Response(JSON.stringify(o({message:"Invalid JSON"}).toResponse()),{status:406});return y=1,e});return Promise.resolve(O&&O.then?O.then(g):g(O))}catch(e){return Promise.reject(e)}}}},q=c(),R=function(e){return function(r){var o=function(e){return Object.entries(e).flatMap(function(e){var r=e[0],t=e[1];return t instanceof j?[r]:"object"==typeof t?o(t).map(function(e){return r+":"+e}):[]})};return{handlerNames:o(r),runMany:function(o,s){try{return Promise.resolve(Promise.all(s.calls.map(function(i,u){try{return Promise.resolve(function(o,s,i){try{var u=v({},o,{body:s.payload});return Promise.resolve(function(e,n){try{var a=(i=function(e){for(var t=e.split(":"),n=r;n&&t.length>0;)if(!(n=n[t.shift()]))return null;return n&&n instanceof j?n:null}(s.name))?Promise.resolve(i.run(u,{})).then(function(e){return{status:200,request:o,response:e.response}}):{request:u,status:404,response:t({entity:"handler"}).toResponse()}}catch(e){return n(e)}var i;return a&&a.then?a.then(void 0,n):a}(0,function(r){return console.error(r),a(r)?(r.data.status>=500&&q.captureException(r,{tags:{reqId:i}}),{request:u,status:r.data.status,response:r.toResponse()}):(q.captureException(r,{tags:{reqId:i}}),null==e.onError||e.onError({callName:s.name,callId:s.id,request:o,error:r,reqId:i}),{request:u,status:500,response:n().toResponse()})}))}catch(e){return Promise.reject(e)}}(o,i,s.requestId)).then(function(r){try{null==e.onRequest||e.onRequest({reqId:s.requestId,callId:i.id,callName:i.name,request:r.request,response:{status:r.status,body:r.response}})}catch(e){q.captureException(e),console.error(e)}return{__typename:"rpc.response.call",id:i.id,name:i.name,status:r.status,result:r.response}})}catch(e){return Promise.reject(e)}}))).then(function(e){return{status:Math.max.apply(Math,e.map(function(e){return e.status})),body:{__typename:"rpc.response",calls:e}}})}catch(e){return Promise.reject(e)}}}}};export{P as Group,j as Handler,R as createServer,_ as rpcMux};
1
+ import{ServiceError as e,validationError as r,notFoundError as t,internalServerError as n,notAcceptableError as o,isServiceError as a}from"@lowerdeck/error";import{provideExecutionContext as s,createExecutionContext as i}from"@lowerdeck/execution-context";import{generateCustomId as u}from"@lowerdeck/id";import{memo as l}from"@lowerdeck/memo";import{getSentry as c}from"@lowerdeck/sentry";import{serialize as d}from"@lowerdeck/serialize";import{v as f}from"@lowerdeck/validation";import*as h from"cookie";function p(e,r){(null==r||r>e.length)&&(r=e.length);for(var t=0,n=Array(r);t<r;t++)n[t]=e[t];return n}function m(e,r){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,r){if(e){if("string"==typeof e)return p(e,r);var t={}.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?p(e,r):void 0}}(e))||r&&e&&"number"==typeof e.length){t&&(e=t);var n=0;return function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function v(){return v=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)({}).hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e},v.apply(null,arguments)}const y="undefined"!=typeof Symbol?Symbol.iterator||(Symbol.iterator=Symbol("Symbol.iterator")):"@@iterator";function g(e,r,t){if(!e.s){if(t instanceof w){if(!t.s)return void(t.o=g.bind(null,e,r));1&r&&(r=t.s),t=t.v}if(t&&t.then)return void t.then(g.bind(null,e,r),g.bind(null,e,2));e.s=r,e.v=t;var n=e.o;n&&n(e)}}var w=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(r,t){var n=new e,o=this.s;if(o){var a=1&o?r:t;if(a){try{g(n,1,a(this.v))}catch(e){g(n,2,e)}return n}return this}return this.o=function(e){try{var o=e.v;1&e.s?g(n,1,r?r(o):o):t?g(n,1,t(o)):g(n,2,o)}catch(e){g(n,2,e)}},n},e}();function b(e){return e instanceof w&&1&e.s}var P=/*#__PURE__*/function(){function e(e){void 0===e&&(e=[]),this._middleware=void 0,this._middleware=e}var r=e.prototype;return r.use=function(r,t){return new e([].concat(this._middleware,[function(e){try{var n,o=function(t){if(n)return t;var o=r(e);return a&&e.sharedMiddlewareMemo.set(a,o),Promise.resolve(o)},a=null==t||null==t.getSharedMemoKey?void 0:t.getSharedMemoKey(e),s=function(){if(a&&e.sharedMiddlewareMemo.has(a))return Promise.resolve(e.sharedMiddlewareMemo.get(a)).then(function(e){return n=1,e})}();return Promise.resolve(s&&s.then?s.then(o):o(s))}catch(e){return Promise.reject(e)}}]))},r.createMiddleware=function(e,r){return function(t){return function(n){try{var o,a=function(r){if(o)return r;var a=e(n,t);return s&&n.sharedMiddlewareMemo.set(s,a),Promise.resolve(a)},s=null==r||null==r.getSharedMemoKey?void 0:r.getSharedMemoKey(n,t),i=function(){if(s&&n.sharedMiddlewareMemo.has(s))return Promise.resolve(n.sharedMiddlewareMemo.get(s)).then(function(e){return o=1,e})}();return Promise.resolve(i&&i.then?i.then(a):a(i))}catch(e){return Promise.reject(e)}}}},r.handler=function(){return new j([].concat(this._middleware))},r.controller=function(e){return e},e}(),j=/*#__PURE__*/function(){function t(e){void 0===e&&(e=[]),this._middleware=void 0,this._handler=void 0,this._validation=void 0,this._middleware=e}var n=t.prototype;return n.do=function(e){if(null!=this._handler)throw new Error("Handler already defined");return this._handler=e,this},n.use=function(e){return this._middleware.push(e),this},n.input=function(e){if(null!=this._validation)throw new Error("Input validation already defined");return this._validation=e,this},n.run=function(t,n){try{var o=function(){return Promise.resolve(a._handler(v({},u,{input:s,body:void 0}))).then(function(e){return{response:e}})},a=this;if(!a._handler)throw new Error("Handler not defined");var s=t.body;if(a._validation){var i=a._validation.validate(t.body);if(!i.success)throw new e(r({errors:i.errors,entity:"call_data"}));s=i.value}var u=v({},n,t,{body:s}),l=function(e,r){if("function"==typeof e[y]){var t,n,o,a=function(e){try{for(;!(t=s.next()).done;)if((e=r(t.value))&&e.then){if(!b(e))return void e.then(a,o||(o=g.bind(null,n=new w,2)));e=e.v}n?g(n,1,e):n=e}catch(e){g(n||(n=new w),2,e)}},s=e[y]();if(a(),s.return){var i=function(e){try{t.done||s.return()}catch(e){}return e};if(n&&n.then)return n.then(i,function(e){throw i(e)});i()}return n}if(!("length"in e))throw new TypeError("Object is not iterable");for(var u=[],l=0;l<e.length;l++)u.push(e[l]);return function(e,r){var t,n,o=-1;return function a(s){try{for(;++o<e.length;)if((s=r(o))&&s.then){if(!b(s))return void s.then(a,n||(n=g.bind(null,t=new w,2)));s=s.v}t?g(t,1,s):t=s}catch(e){g(t||(t=new w),2,e)}}(),t}(u,function(e){return r(u[e])})}(a._middleware,function(e){return Promise.resolve(e(u)).then(function(e){e&&(u=v({},u,e))})});return Promise.resolve(l&&l.then?l.then(o):o())}catch(e){return Promise.reject(e)}},t}(),M=c(),S=f.object({calls:f.array(f.object({id:f.string(),name:f.string(),payload:f.any()}))}),_=function(e,a){var c=new Map(a.flatMap(function(e,r){return e.handlerNames.map(function(e){return[e,r]})}));return{path:e.path,fetch:function(f){try{var p,v,y,g=function(e){var o,p,v,g;if(y)return e;var w=f.headers.get("sentry-trace"),P=null!=(o=Array.isArray(w)?w.join(","):w)?o:void 0,_=f.headers.get("baggage"),O=function(e){if("string"==typeof e){var r=e.split(",").map(function(e){return e.trim()}).filter(Boolean);return r.length>0?r[0]:void 0}}(null!=(p=null!=(v=null!=(g=f.headers.get("lowerdeck-connecting-ip"))?g:f.headers.get("cf-connecting-ip"))?v:f.headers.get("x-forwarded-for"))?p:f.headers.get("x-real-ip")),x=new Headers;if(b)for(var I=0,k=Object.entries(q);I<k.length;I++){var A=k[I];x.append(A[0],A[1])}return Promise.resolve(M.withIsolationScope(function(){try{return Promise.resolve(M.continueTrace({sentryTrace:P,baggage:_},function(){try{var e,o;return Promise.resolve(M.startSpan({name:"rpc request",op:"rpc.server",attributes:{ip:O,transport:"http",ua:null!=(e=f.headers.get("user-agent"))?e:"",origin:null!=(o=f.headers.get("origin"))?o:""}},function(){try{try{var e,o=[],p=u("req_"),v=l(function(){var e;return h.parse(null!=(e=f.headers.get("cookie"))?e:"")}),y={url:f.url,headers:f.headers,query:j.searchParams,body:R,rawBody:R,ip:O,requestId:p,getCookies:function(){return v()},getCookie:function(e){return v()[e]},setCookie:function(e,r,t){var n=h.serialize(e,r,t);x.append("Set-Cookie",n)},beforeSend:function(e){o.push(e)},sharedMiddlewareMemo:new Map,appendHeaders:function(e){for(var r=0,t=Object.entries(e);r<t.length;r++){var n=t[r],o=n[0],a=n[1];if(Array.isArray(a))for(var s,i=m(a);!(s=i()).done;)x.append(o,s.value);else x.append(o,a)}}};return M.getCurrentScope().setContext("rpc.request",{url:f.url,query:Object.fromEntries(j.searchParams.entries())}),M.getCurrentScope().addAttachment({filename:"rpc.request.body.json",data:R,contentType:"application/json"}),Promise.resolve(s(i({type:"request",contextId:p,ip:null!=O?O:"0.0.0.0",userAgent:null!=(e=f.headers.get("user-agent"))?e:""}),function(){try{var e=new Map,n={body:{__typename:"rpc.response",calls:[]},status:200},s=j.pathname.split("/").filter(Boolean),i=s[s.length-1],l="$"==i[0];if(l){var f,h=i.slice(1),v=c.get(h);if(null==v)return Promise.resolve(new Response(JSON.stringify(t({entity:"handler"}).toResponse()),{status:404,headers:x}));var g=null!=(f=e.get(v))?f:[];g.push({id:u("call_"),name:h,payload:R}),e.set(v,g)}else{var w=S.validate(R);if(!w.success)return Promise.resolve(new Response(JSON.stringify(r({errors:w.errors,entity:"request_data"}).toResponse()),{status:406,headers:x}));for(var b,P=m(w.value.calls);!(b=P()).done;){var M,_=b.value,q=c.get(_.name);if(null==q)return Promise.resolve(new Response(JSON.stringify(t({entity:"handler"}).toResponse()),{status:404,headers:x}));var O=null!=(M=e.get(q))?M:[];O.push(_),e.set(q,O)}}return Promise.resolve(Promise.all(Array.from(e.entries()).map(function(e){var r=e[0],t=e[1];try{return Promise.resolve(a[r].runMany(y,{requestId:p,calls:t})).then(function(e){var r;n.status=Math.max(n.status,e.status),(r=n.body.calls).push.apply(r,e.body.calls)})}catch(e){return Promise.reject(e)}}))).then(function(){return x.append("x-req-id",p),x.append("content-type","application/rpc+json"),x.append("x-powered-by","lowerdeck RPC"),Promise.resolve(Promise.all(o.map(function(e){return e()}))).then(function(){return new Response(d.encode(l?n.body.calls[0].result:n.body),{status:n.status,headers:x})})})}catch(e){return Promise.reject(e)}}))}catch(e){return console.error(e),M.captureException(e),Promise.resolve(new Response(JSON.stringify(n().toResponse()),{status:500,headers:x}))}}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}}))},w=null!=(p=f.headers.get("origin"))?p:"",b=!1;if(e.cors&&"domains"in e.cors)try{var P=new URL(w).hostname.split(".").slice(-2).join(".");b=e.cors.domains.includes(P)}catch(e){}else e.cors&&"check"in e.cors&&(b=e.cors.check(w));var j=new URL(f.url),_=null==(v=e.cors)||null==(v=v.headers)?void 0:v.join(", ");_&&(_=(", "+_).trim());var q=b?{"access-control-allow-origin":w,"access-control-allow-methods":"POST, OPTIONS","access-control-allow-headers":"Content-Type, Authorization, Baggage, Sentry-Trace"+(null!=_?_:""),"access-control-max-age":"604800","access-control-allow-credentials":"true"}:{};if("OPTIONS"==f.method)return Promise.resolve(b?new Response(null,{status:204,headers:q}):new Response(null,{status:403}));var R=null,O=function(e,r){try{var t=e()}catch(e){return r()}return t&&t.then?t.then(void 0,r):t}(function(){var e=d.decode;return Promise.resolve(f.text()).then(function(r){R=e.call(d,r)})},function(){var e=new Response(JSON.stringify(o({message:"Invalid JSON"}).toResponse()),{status:406});return y=1,e});return Promise.resolve(O&&O.then?O.then(g):g(O))}catch(e){return Promise.reject(e)}}}},q=c(),R=function(e){return function(r){var o=function(e){return Object.entries(e).flatMap(function(e){var r=e[0],t=e[1];return t instanceof j?[r]:"object"==typeof t?o(t).map(function(e){return r+":"+e}):[]})};return{handlerNames:o(r),runMany:function(o,s){try{return Promise.resolve(Promise.all(s.calls.map(function(i,u){try{return Promise.resolve(function(o,s,i){try{var u=v({},o,{body:s.payload});return Promise.resolve(function(e,n){try{var a=(i=function(e){for(var t=e.split(":"),n=r;n&&t.length>0;)if(!(n=n[t.shift()]))return null;return n&&n instanceof j?n:null}(s.name))?Promise.resolve(i.run(u,{})).then(function(e){return{status:200,request:o,response:e.response}}):{request:u,status:404,response:t({entity:"handler"}).toResponse()}}catch(e){return n(e)}var i;return a&&a.then?a.then(void 0,n):a}(0,function(r){return console.error(r),a(r)?(r.data.status>=500&&q.captureException(r,{tags:{reqId:i}}),{request:u,status:r.data.status,response:r.toResponse()}):(q.captureException(r,{tags:{reqId:i}}),null==e.onError||e.onError({callName:s.name,callId:s.id,request:o,error:r,reqId:i}),{request:u,status:500,response:n().toResponse()})}))}catch(e){return Promise.reject(e)}}(o,i,s.requestId)).then(function(r){try{null==e.onRequest||e.onRequest({reqId:s.requestId,callId:i.id,callName:i.name,request:r.request,response:{status:r.status,body:r.response}})}catch(e){q.captureException(e),console.error(e)}return{__typename:"rpc.response.call",id:i.id,name:i.name,status:r.status,result:r.response}})}catch(e){return Promise.reject(e)}}))).then(function(e){return{status:Math.max.apply(Math,e.map(function(e){return e.status})),body:{__typename:"rpc.response",calls:e}}})}catch(e){return Promise.reject(e)}}}}};export{P as Group,j as Handler,R as createServer,_ as rpcMux};
2
2
  //# sourceMappingURL=index.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.module.js","sources":["../src/controller.ts","../src/rpcMux.ts","../src/extractIp.ts","../src/server.ts"],"sourcesContent":["import { ServiceError, validationError } from '@lowerdeck/error';\nimport { ValidationType } from '@lowerdeck/validation';\nimport * as Cookie from 'cookie';\n\nexport type Method = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\nexport interface ServiceRequest {\n query: URLSearchParams;\n headers: Headers;\n url: string;\n ip?: string;\n body: any;\n rawBody: any;\n requestId: string;\n\n getCookies: () => Record<string, string | undefined>;\n getCookie: (name: string) => string | undefined;\n setCookie: (name: string, value: string, opts?: Cookie.SerializeOptions) => void;\n\n sharedMiddlewareMemo: Map<string, Promise<any>>;\n beforeSend: (handler: () => Promise<any>) => void;\n appendHeaders: (headers: Record<string, string | string[]>) => void;\n}\n\nexport type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};\nexport type ExtendContext<C extends object, E> = E extends object ? Simplify<C & E> : C;\n\nexport class Group<Context extends { [key: string]: any } = {}> {\n constructor(\n private _middleware: Array<(ctx: Context & ServiceRequest) => Promise<any>> = []\n ) {}\n\n use<T extends { [key: string]: any } | undefined | void>(\n handler: (ctx: Context & ServiceRequest) => Promise<T>,\n opts?: {\n getSharedMemoKey?: (ctx: Context & ServiceRequest) => string;\n }\n ) {\n let middleware = async (ctx: Parameters<typeof handler>[0]): Promise<T> => {\n let key = opts?.getSharedMemoKey?.(ctx);\n if (key && ctx.sharedMiddlewareMemo.has(key)) {\n return await ctx.sharedMiddlewareMemo.get(key)!;\n }\n\n let res = handler(ctx);\n if (key) ctx.sharedMiddlewareMemo.set(key, res);\n\n return await res;\n };\n\n return new Group<Simplify<Context & T>>([...this._middleware, middleware]);\n }\n\n createMiddleware<T extends { [key: string]: any }, P = void>(\n handler: (ctx: Context & ServiceRequest, input: P) => Promise<T>,\n opts?: {\n getSharedMemoKey?: (ctx: Context & ServiceRequest, input: P) => string;\n }\n ) {\n return (input: P) =>\n async (ctx: Context & ServiceRequest): Promise<T> => {\n let key = opts?.getSharedMemoKey?.(ctx, input);\n if (key && ctx.sharedMiddlewareMemo.has(key)) {\n return await ctx.sharedMiddlewareMemo.get(key)!;\n }\n\n let res = handler(ctx, input);\n if (key) ctx.sharedMiddlewareMemo.set(key, res);\n\n return await res;\n };\n }\n\n handler() {\n return new Handler([...this._middleware]);\n }\n\n controller<\n HandlersAndSubControllers extends {\n [key: string]: Handler<any, any, any> | Controller<any>;\n }\n >(handlers: HandlersAndSubControllers): Controller<HandlersAndSubControllers> {\n return handlers;\n }\n}\n\nexport type Controller<\n HandlersAndSubControllers extends { [key: string]: Handler<any, any, any> | Controller<any> }\n> = HandlersAndSubControllers;\n\nexport type InferControllerType<T> = T extends Controller<infer U> ? U : never;\n\nexport type InferClient<\n HandlersAndSubControllers extends { [key: string]: Handler<any, any, any> | Controller<any> }\n> = {\n [K in keyof HandlersAndSubControllers]: HandlersAndSubControllers[K] extends Handler<\n infer I,\n infer O,\n infer C\n >\n ? ((\n input: I,\n opts?: { headers?: Record<string, string>; query?: Record<string, string> }\n ) => Promise<O>) & {\n getFull: (\n input: I,\n opts?: { headers?: Record<string, string>; query?: Record<string, string> }\n ) => Promise<{\n data: O;\n status: number;\n headers: Record<string, string>;\n }>;\n }\n : HandlersAndSubControllers[K] extends Controller<infer U>\n ? InferClient<U>\n : never;\n};\n\nexport class Handler<Input, Output, Context extends { [key: string]: any } = {}> {\n private _handler!: (\n ctx: Context & Omit<ServiceRequest, 'body'> & { input: Input }\n ) => Promise<Output>;\n private _validation: ValidationType<Input> | undefined;\n\n constructor(\n private _middleware: Array<(ctx: Context & ServiceRequest) => Promise<any>> = []\n ) {}\n\n do<HandlerOutput>(\n handler: (\n ctx: Context & Omit<ServiceRequest, 'body'> & { input: Input }\n ) => Promise<HandlerOutput>\n ) {\n if (this._handler != undefined) throw new Error('Handler already defined');\n\n // @ts-ignore\n this._handler = handler;\n\n return this as any as Handler<Input, HandlerOutput, Context>;\n }\n\n use<T extends { [key: string]: any } = {}>(\n handler: (ctx: Context & ServiceRequest) => Promise<T | undefined | void>\n ) {\n this._middleware.push(handler);\n return this as any as Handler<Input, Output, ExtendContext<Context, T>>;\n }\n\n input<HandlerInput>(validation: ValidationType<HandlerInput>) {\n if (this._validation != undefined) throw new Error('Input validation already defined');\n\n // @ts-ignore\n this._validation = validation;\n\n return this as any as Handler<HandlerInput, Output, Context>;\n }\n\n async run(\n req: ServiceRequest,\n initialContext: any\n ): Promise<{\n response: Output;\n }> {\n if (!this._handler) throw new Error('Handler not defined');\n\n let input = req.body as Input;\n\n if (this._validation) {\n let valRes = this._validation.validate(req.body);\n\n if (!valRes.success) {\n throw new ServiceError(\n validationError({ errors: valRes.errors, entity: 'call_data' })\n );\n }\n\n input = valRes.value;\n }\n\n let ctx = {\n ...initialContext,\n ...req,\n\n // Always use the sanitized input\n body: input\n };\n\n for (let mw of this._middleware) {\n let res = await mw(ctx);\n if (res) ctx = { ...ctx, ...res };\n }\n\n let res = await this._handler({\n ...ctx,\n input,\n body: undefined\n });\n\n return {\n response: res\n };\n }\n}\n","import {\n internalServerError,\n notAcceptableError,\n notFoundError,\n validationError\n} from '@lowerdeck/error';\nimport { createExecutionContext, provideExecutionContext } from '@lowerdeck/execution-context';\nimport { generateCustomId } from '@lowerdeck/id';\nimport { memo } from '@lowerdeck/memo';\nimport { getSentry } from '@lowerdeck/sentry';\nimport { serialize } from '@lowerdeck/serialize';\nimport { v } from '@lowerdeck/validation';\nimport * as Cookie from 'cookie';\nimport { ServiceRequest } from './controller';\nimport { parseForwardedFor } from './extractIp';\n\nlet Sentry = getSentry();\n\nlet validation = v.object({\n calls: v.array(\n v.object({\n id: v.string(),\n name: v.string(),\n payload: v.any()\n })\n )\n});\n\nexport let rpcMux = (\n opts: {\n path: string;\n cors?: {\n headers?: string[];\n } & ({ domains: string[] } | { check: (origin: string) => boolean });\n },\n rpcs: {\n handlerNames: string[];\n runMany: (\n req: ServiceRequest,\n body: {\n requestId: string;\n calls: {\n id: string;\n name: string;\n payload: any;\n }[];\n }\n ) => Promise<{\n status: number;\n body: {\n calls: any[];\n };\n }>;\n }[]\n) => {\n let handlerNameToRpcMap = new Map<string, number>(\n rpcs.flatMap((rpc, i) => rpc.handlerNames.map(name => [name, i]))\n );\n\n return {\n path: opts.path,\n\n fetch: async (req: any): Promise<any> => {\n let origin = req.headers.get('origin') ?? '';\n let corsOk = false;\n\n if (opts.cors && 'domains' in opts.cors) {\n try {\n let url = new URL(origin);\n let rootDomain = url.hostname.split('.').slice(-2).join('.');\n corsOk = opts.cors.domains.includes(rootDomain);\n } catch (e) {\n // Ignore -> no cors\n }\n } else if (opts.cors && 'check' in opts.cors) {\n corsOk = opts.cors.check(origin);\n }\n\n let url = new URL(req.url);\n\n let additionalCorsHeaders = opts.cors?.headers?.join(', ');\n if (additionalCorsHeaders) additionalCorsHeaders = `, ${additionalCorsHeaders}`.trim();\n\n let corsHeaders: Record<string, string> = corsOk\n ? {\n 'access-control-allow-origin': origin,\n 'access-control-allow-methods': 'POST, OPTIONS',\n 'access-control-allow-headers': `Content-Type, Authorization, Baggage, Sentry-Trace${\n additionalCorsHeaders ?? ''\n }`,\n 'access-control-max-age': '604800',\n 'access-control-allow-credentials': 'true'\n }\n : {};\n\n if (req.method == 'OPTIONS') {\n if (corsOk) {\n return new Response(null, {\n status: 204,\n headers: corsHeaders\n });\n }\n\n return new Response(null, { status: 403 });\n }\n\n let body: any = null;\n\n try {\n body = serialize.decode(await req.text());\n } catch (e) {\n return new Response(\n JSON.stringify(notAcceptableError({ message: 'Invalid JSON' }).toResponse()),\n { status: 406 }\n );\n }\n\n let sentryTraceHeaders = req.headers.get('sentry-trace');\n let sentryTrace =\n (Array.isArray(sentryTraceHeaders)\n ? sentryTraceHeaders.join(',')\n : sentryTraceHeaders) ?? undefined;\n let baggage = req.headers.get('baggage');\n\n let ip = parseForwardedFor(\n req.headers.get('lowerdeck-connecting-ip') ??\n req.headers.get('cf-connecting-ip') ??\n req.headers.get('x-forwarded-for') ??\n req.headers.get('x-real-ip')\n );\n\n let headers = new Headers();\n\n if (corsOk) {\n for (let [key, value] of Object.entries(corsHeaders)) {\n headers.append(key, value);\n }\n }\n\n return await Sentry.withIsolationScope(\n async () =>\n await Sentry.continueTrace(\n { sentryTrace, baggage },\n async () =>\n await Sentry.startSpan(\n {\n name: 'rpc request',\n op: 'rpc.server',\n attributes: {\n ip,\n transport: 'http',\n ua: req.headers.get('user-agent') ?? '',\n origin: req.headers.get('origin') ?? ''\n }\n },\n async () => {\n try {\n let beforeSends: Array<() => Promise<any>> = [];\n let id = generateCustomId('req_');\n\n let parseCookies = memo(() =>\n Cookie.parse(req.headers.get('cookie') ?? '')\n );\n\n let request: ServiceRequest = {\n url: req.url,\n headers: req.headers,\n query: url.searchParams,\n body,\n rawBody: body,\n ip,\n requestId: id,\n\n getCookies: () => parseCookies(),\n getCookie: (name: string) => parseCookies()[name],\n setCookie: (name: string, value: string, opts?: any) => {\n let cookie = Cookie.serialize(name, value, opts);\n // @ts-ignore\n headers.append('Set-Cookie', cookie);\n },\n\n beforeSend: (handler: () => Promise<any>) => {\n beforeSends.push(handler);\n },\n\n sharedMiddlewareMemo: new Map<string, Promise<any>>(),\n\n appendHeaders: (newHeaders: Record<string, string | string[]>) => {\n for (let [key, value] of Object.entries(newHeaders)) {\n if (Array.isArray(value)) {\n for (let v of value) headers.append(key, v);\n } else {\n headers.append(key, value);\n }\n }\n }\n };\n\n Sentry.getCurrentScope().setContext('rpc.request', {\n url: req.url,\n query: Object.fromEntries(url.searchParams.entries())\n });\n\n Sentry.getCurrentScope().addAttachment({\n filename: 'rpc.request.body.json',\n data: body,\n contentType: 'application/json'\n });\n\n return provideExecutionContext(\n createExecutionContext({\n type: 'request',\n contextId: id,\n ip: ip ?? '0.0.0.0',\n userAgent: req.headers.get('user-agent') ?? ''\n }),\n async () => {\n let callsByRpc = new Map<\n number,\n { id: string; name: string; payload: any }[]\n >();\n\n let resRef = {\n body: {\n __typename: 'rpc.response',\n calls: [] as any[]\n },\n status: 200\n };\n\n let pathParts = url.pathname.split('/').filter(Boolean);\n let lastPart = pathParts[pathParts.length - 1];\n\n if (lastPart[0] == '$') {\n let id = lastPart.slice(1);\n let rpcIndex = handlerNameToRpcMap.get(id);\n if (rpcIndex == undefined) {\n return new Response(\n JSON.stringify(\n notFoundError({ entity: 'handler' }).toResponse()\n ),\n { status: 404, headers }\n );\n }\n\n let calls = callsByRpc.get(rpcIndex) ?? [];\n calls.push({\n id: generateCustomId('call_'),\n name: id,\n payload: body\n });\n callsByRpc.set(rpcIndex, calls);\n } else {\n let valRes = validation.validate(body);\n if (!valRes.success) {\n return new Response(\n JSON.stringify(\n validationError({\n errors: valRes.errors,\n entity: 'request_data'\n }).toResponse()\n ),\n { status: 406, headers }\n );\n }\n\n for (let call of valRes.value.calls) {\n let rpcIndex = handlerNameToRpcMap.get(call.name);\n if (rpcIndex == undefined) {\n return new Response(\n JSON.stringify(\n notFoundError({ entity: 'handler' }).toResponse()\n ),\n { status: 404, headers }\n );\n }\n\n let calls = callsByRpc.get(rpcIndex) ?? [];\n calls.push(call as any);\n callsByRpc.set(rpcIndex, calls);\n }\n }\n\n await Promise.all(\n Array.from(callsByRpc.entries()).map(async ([rpcIndex, calls]) => {\n let rpc = rpcs[rpcIndex];\n let res = await rpc.runMany(request, {\n requestId: id,\n calls\n });\n\n resRef.status = Math.max(resRef.status, res.status);\n resRef.body.calls.push(...res.body.calls);\n })\n );\n\n headers.append('x-req-id', id);\n headers.append('content-type', 'application/rpc+json');\n headers.append('x-powered-by', 'lowerdeck RPC');\n\n await Promise.all(beforeSends.map(s => s()));\n\n return new Response(serialize.encode(resRef.body), {\n status: resRef.status,\n headers\n });\n }\n );\n } catch (e) {\n console.error(e);\n\n Sentry.captureException(e);\n\n return new Response(JSON.stringify(internalServerError().toResponse()), {\n status: 500,\n headers\n });\n }\n }\n )\n )\n );\n }\n };\n};\n","export let parseForwardedFor = (xForwardedForHeader?: string | null | undefined) => {\n if (typeof xForwardedForHeader != 'string') return undefined;\n\n let ips = xForwardedForHeader\n .split(',')\n .map(ip => ip.trim())\n .filter(Boolean);\n return ips.length > 0 ? ips[0] : undefined;\n};\n","import { internalServerError, isServiceError, notFoundError } from '@lowerdeck/error';\nimport { getSentry } from '@lowerdeck/sentry';\nimport { Controller, Handler, ServiceRequest } from './controller';\n\nlet Sentry = getSentry();\n\nexport let createServer =\n (opts: {\n onError?: (opts: {\n request: ServiceRequest;\n error: any;\n reqId: string;\n callId: string;\n callName: string;\n }) => void;\n onRequest?: (opts: {\n reqId: string;\n callId: string;\n callName: string;\n request: ServiceRequest;\n response: { status: number; body: any };\n }) => void;\n }) =>\n (controller: Controller<any>) => {\n let findHandler = (name: string): Handler<any, any, any> | null => {\n let parts = name.split(':');\n let current = controller;\n\n while (current && parts.length > 0) {\n current = current[parts.shift()!];\n if (!current) return null;\n }\n\n if (current && current instanceof Handler) return current;\n\n return null;\n };\n\n let getSupportedHandlerNames = (controller: Controller<any>): string[] =>\n Object.entries(controller).flatMap(([key, value]) => {\n if (value instanceof Handler) return [key];\n if (typeof value == 'object')\n return getSupportedHandlerNames(value).map(name => `${key}:${name}`);\n return [];\n });\n\n let handlerNames = getSupportedHandlerNames(controller);\n\n let run = async (\n req: ServiceRequest,\n call: { id: string; name: string; payload: any },\n reqId: string\n ): Promise<{\n response: any;\n status: number;\n request: ServiceRequest;\n }> => {\n let request = { ...req, body: call.payload };\n\n try {\n let handler = findHandler(call.name);\n\n if (!handler) {\n return {\n request,\n status: 404,\n response: notFoundError({ entity: 'handler' }).toResponse()\n };\n }\n\n let response = await handler.run(request, {});\n\n return {\n status: 200,\n request: req,\n response: response.response\n };\n } catch (e) {\n console.error(e);\n\n if (isServiceError(e)) {\n if (e.data.status >= 500) {\n Sentry.captureException(e, {\n tags: { reqId }\n });\n }\n\n return {\n request,\n status: e.data.status,\n response: e.toResponse()\n };\n }\n\n Sentry.captureException(e, {\n tags: { reqId }\n });\n\n opts.onError?.({\n callName: call.name,\n callId: call.id,\n request: req,\n error: e,\n reqId\n });\n\n return {\n request,\n status: 500,\n response: internalServerError().toResponse()\n };\n }\n };\n\n let runMany = async (\n req: ServiceRequest,\n body: {\n calls: {\n id: string;\n name: string;\n payload: any;\n }[];\n requestId: string;\n }\n ): Promise<{\n status: number;\n body: any;\n }> => {\n let callRes = await Promise.all(\n body.calls.map(async (call, i) => {\n let res = await run(req, call as any, body.requestId);\n\n try {\n opts.onRequest?.({\n reqId: body.requestId,\n callId: call.id,\n callName: call.name,\n request: res.request,\n response: { status: res.status, body: res.response }\n });\n } catch (e) {\n Sentry.captureException(e);\n console.error(e);\n }\n\n return {\n __typename: 'rpc.response.call',\n id: call.id,\n name: call.name,\n status: res.status,\n result: res.response\n };\n })\n );\n\n return {\n status: Math.max(...callRes.map(c => c.status)),\n body: {\n __typename: 'rpc.response',\n calls: callRes\n }\n };\n };\n\n return {\n handlerNames,\n runMany\n\n // fetch,\n\n // http: async (\n // req: IncomingMessage & {\n // body: any;\n // },\n // res: ServerResponse & { send: (body: any) => void }\n // ) => {\n // let headers = new Headers(\n // Object.fromEntries(\n // Object.entries(req.headers).map(([key, value]) => [\n // key,\n // value === undefined ? '' : String(value)\n // ])\n // )\n // );\n // let url = new URL(req.url ?? '', `http://${req.headers.host}`);\n\n // let request = new Request(url.toString(), {\n // method: req.method,\n // headers,\n // body: JSON.stringify(req.body)\n // });\n\n // let response = await fetch(request);\n\n // res.statusCode = response.status;\n\n // for (let [key, value] of response.headers.entries()) {\n // res.setHeader(key, value);\n // }\n\n // res.send(response.body);\n // }\n };\n };\n"],"names":["_settle","pact","state","value","s","_Pact","o","bind","v","then","observer","prototype","onFulfilled","onRejected","result","this","callback","e","_this","_isSettledPact","thenable","Group","_middleware","_proto","use","handler","opts","concat","ctx","_exit","_temp2","_result","res","key","sharedMiddlewareMemo","set","Promise","resolve","getSharedMemoKey","_temp","has","get","_await$ctx$sharedMidd","reject","createMiddleware","input","_exit2","_temp4","_result2","_temp3","_await$ctx$sharedMidd2","Handler","controller","handlers","_handler","_validation","_proto2","undefined","Error","push","validation","run","req","initialContext","_temp6","_extends","body","response","valRes","validate","success","ServiceError","validationError","errors","entity","_temp5","_forOf","mw","Sentry","getSentry","object","calls","array","id","string","name","payload","any","rpcMux","rpcs","handlerNameToRpcMap","Map","flatMap","rpc","i","handlerNames","map","path","fetch","_req$headers$get6","_opts$cors","_ref","_ref2","_ref3","_req$headers$get","sentryTraceHeaders","headers","sentryTrace","Array","isArray","join","baggage","ip","xForwardedForHeader","ips","split","trim","filter","Boolean","length","parseForwardedFor","Headers","corsOk","_i","_Object$entries","Object","entries","corsHeaders","_Object$entries$_i","append","withIsolationScope","continueTrace","_req$headers$get2","_req$headers$get3","startSpan","op","attributes","transport","ua","origin","_req$headers$get5","beforeSends","generateCustomId","parseCookies","memo","_req$headers$get4","Cookie","parse","request","url","query","searchParams","rawBody","requestId","getCookies","getCookie","setCookie","cookie","serialize","beforeSend","appendHeaders","newHeaders","_i2","_Object$entries2","_Object$entries2$_i","_step","_iterator","_createForOfIteratorHelperLoose","done","getCurrentScope","setContext","fromEntries","addAttachment","filename","data","contentType","provideExecutionContext","createExecutionContext","type","contextId","userAgent","callsByRpc","resRef","__typename","status","pathParts","pathname","lastPart","_callsByRpc$get","slice","rpcIndex","Response","JSON","stringify","notFoundError","toResponse","_iterator2","_step2","_callsByRpc$get2","call","all","from","_ref4","runMany","_resRef$body$calls","Math","max","apply","encode","console","error","captureException","internalServerError","cors","rootDomain","URL","hostname","domains","includes","check","additionalCorsHeaders","method","_catch","_decode","decode","text","_req$text","_Response","notAcceptableError","message","createServer","getSupportedHandlerNames","reqId","parts","current","shift","findHandler","isServiceError","tags","onError","callName","callId","onRequest","callRes","c"],"mappings":"mmDA6HY,SAAAA,EAAAC,EAAAC,EAAAC,GANF,IAAAF,EAAAG,EAEa,CACb,GAAAD,aAAAE,EAA+C,CAEvD,IAAAF,EAAAC,EAYE,cADaE,EAAAN,EAAAO,KAAA,KAAAN,EAAAC,IAVM,EAAXA,IACNA,EAAAC,EAAAC,GAOFD,EAAIA,EAAaK,EAQnB,GAAAL,GAC2EA,EAAAM,KAGzE,YADAN,EAAAM,KAAgBT,EAAAO,UAAMN,EAASC,GAAAF,EAAAO,KAAA,KAAAN,EAAA,IAIjCA,EAAAG,EAA4DF,EAC1DD,EAAAO,EAAAL,EAAmC,IAAAO,EAAUT,EAAAK,KAG7CI,EAAIT,GAKN,KAlIWI,eAAK,WAEN,SAAAA,IAAA,CAqDR,OAtDFA,EAAAM,wBACkFC,EAAAC,OAAxEC,EAAW,IAAAT,EACjBH,EAAAa,KAAAX,KAEDF,EACqD,CAKtD,IAAAc,EAAiB,IAAOJ,EAAkDC,OACpE,SAEK,EAAAG,EAAUD,KAAAP,UAClBS,GAEDjB,EAAAc,EAAU,EAAAG,EACV,UAGF,OAAEF,iBAKYT,EAAA,SAAAY,aAQNA,EAAMV,EACN,IAAAJ,MACK,EAAAQ,EAAUA,EAAAT,GAA4BA,GAC9CU,IAEGC,IAAaD,EAAMV,YAIzB,CAAA,MAAEc,GACNjB,EAACc,EAAA,EAAAG,KAIAH,CAED,EAKET,EAvDc,GAwIM,SAAAc,EAAgBC,GAEpC,OAAAA,aAASf,GAAqB,EAAAe,EAAAhB,CAE9B,CA5IS,IAAAiB,0BACX,SAAAA,EACUC,QAAAA,IAAAA,IAAAA,EAAsE,IAAEP,KAAxEO,iBAAA,EAAAP,KAAWO,YAAXA,CACP,CAAC,IAAAC,EAAAF,EAAAV,UAqDHU,OArDGE,EAEJC,IAAA,SACEC,EACAC,GAgBA,WAAWL,KAAKM,OAA4BZ,KAAKO,aAZnC,SAAUM,GAAkD,IAAA,IASxDC,EATwDC,EAAAA,SAAAC,GAAAF,GAAAA,SAAAE,EAMxE,IAAIC,EAAMP,EAAQG,GAC8B,OAA5CK,GAAKL,EAAIM,qBAAqBC,IAAIF,EAAKD,GAAKI,QAAAC,QAEnCL,EAAGH,EARZI,EAAU,MAAJP,SAAAA,EAAMY,wBAANZ,EAAMY,iBAAmBV,GAAKW,EACpCN,WAAAA,GAAAA,GAAOL,EAAIM,qBAAqBM,IAAIP,GAAI,OAAAG,QAAAC,QAC7BT,EAAIM,qBAAqBO,IAAIR,IAAKxB,KAAA,SAAAiC,UAAAb,IAAAa,CAAA,EAAA,CAD7CT,GAC6C,OAAAG,QAAAC,QAAAE,GAAAA,EAAA9B,KAAA8B,EAAA9B,KAAAqB,GAAAA,EAAAS,GAOnD,CAAC,MAAAtB,GAAA,OAAAmB,QAAAO,OAAA1B,EAED,CAAA,IACF,EAACM,EAEDqB,iBAAA,SACEnB,EACAC,GAIA,gBAAQmB,GAAQ,OAAA,SACPjB,GAA6C,IAAA,IASlCkB,EATkCC,EAAAA,SAAAC,GAAAF,GAAAA,SAAAE,EAMlD,IAAIhB,EAAMP,EAAQG,EAAKiB,GACyB,OAA5CZ,GAAKL,EAAIM,qBAAqBC,IAAIF,EAAKD,GAAKI,QAAAC,QAEnCL,EAAG,EARZC,EAAMP,MAAAA,GAAsB,MAAtBA,EAAMY,sBAAgB,EAAtBZ,EAAMY,iBAAmBV,EAAKiB,GAAOI,EAC3ChB,WAAAA,GAAAA,GAAOL,EAAIM,qBAAqBM,IAAIP,UAAIG,QAAAC,QAC7BT,EAAIM,qBAAqBO,IAAIR,IAAKxB,KAAA,SAAAyC,UAAAJ,IAAAI,CAAA,EAAA,CAD7CjB,GAC6C,OAAAG,QAAAC,QAAAY,GAAAA,EAAAxC,KAAAwC,EAAAxC,KAAAsC,GAAAA,EAAAE,GAOnD,CAAC,MAAAhC,GAAAmB,OAAAA,QAAAO,OAAA1B,EACL,CAAA,CAAA,CAAA,EAACM,EAEDE,QAAA,WACE,OAAO,IAAI0B,EAAO,GAAAxB,OAAKZ,KAAKO,aAC9B,EAACC,EAED6B,WAAA,SAIEC,GACA,OAAOA,CACT,EAAChC,CAAA,IAmCU8B,eAMX,WAAA,SAAAA,EACU7B,YAAAA,IAAAA,EAAsE,IAAtEA,KAAAA,iBANFgC,EAAAA,KAAAA,qBAGAC,iBAAW,EAGTxC,KAAWO,YAAXA,CACP,CAAC,IAAAkC,EAAAL,EAAAxC,UA2EH,OA3EG6C,EAAA,GAEJ,SACE/B,GAIA,GAAqBgC,MAAjB1C,KAAKuC,SAAuB,MAAU,IAAAI,MAAM,2BAKhD,OAFA3C,KAAKuC,SAAW7B,MAGlB,EAAC+B,EAEDhC,IAAA,SACEC,GAGA,OADAV,KAAKO,YAAYqC,KAAKlC,GACfV,IACT,EAACyC,EAEDX,MAAA,SAAoBe,GAClB,GAAwBH,MAApB1C,KAAKwC,YAA0B,MAAU,IAAAG,MAAM,oCAKnD,OAFA3C,KAAKwC,YAAcK,EAEZ7C,IACT,EAACyC,EAEKK,IAAG,SACPC,EACAC,OAAmBC,IAAAA,EAAAA,WAAA5B,OAAAA,QAAAC,QAiCHnB,EAAKoC,SAAQW,EAAA,CAAA,EACxBrC,EACHiB,CAAAA,MAAAA,EACAqB,UAAMT,MACNhD,KAJEuB,SAAAA,GAMJ,MAAO,CACLmC,SAAUnC,EACV,EAAAd,EAAAA,EArCGH,KAAL,IAAKG,EAAKoC,SAAU,MAAU,IAAAI,MAAM,uBAEpC,IAAIb,EAAQiB,EAAII,KAEhB,GAAIhD,EAAKqC,YAAa,CACpB,IAAIa,EAASlD,EAAKqC,YAAYc,SAASP,EAAII,MAE3C,IAAKE,EAAOE,QACV,MAAU,IAAAC,EACRC,EAAgB,CAAEC,OAAQL,EAAOK,OAAQC,OAAQ,eAIrD7B,EAAQuB,EAAOjE,KACjB,CAEA,IAAIyB,EAAGqC,EACFF,CAAAA,EAAAA,EACAD,EAGHI,CAAAA,KAAMrB,IACN8B,6uBAAAC,CAEa1D,EAAKI,qBAAXuD,UAAwBzC,QAAAC,QACfwC,EAAGjD,IAAInB,KAAnBuB,SAAAA,GACAA,IAAKJ,EAAGqC,EAAQrC,CAAAA,EAAAA,EAAQI,GAAM,EACpC,GAAC,OAAAI,QAAAC,QAAAsC,GAAAA,EAAAlE,KAAAkE,EAAAlE,KAAAuD,GAAAA,IAWH,CAAC,MAAA/C,GAAAmB,OAAAA,QAAAO,OAAA1B,EAAA,CAAA,EAAAkC,CAAA,CA7ED,GC5GE2B,EAASC,IAETnB,EAAapD,EAAEwE,OAAO,CACxBC,MAAOzE,EAAE0E,MACP1E,EAAEwE,OAAO,CACPG,GAAI3E,EAAE4E,SACNC,KAAM7E,EAAE4E,SACRE,QAAS9E,EAAE+E,WAKNC,EAAS,SAClB9D,EAMA+D,GAoBA,IAAIC,EAAsB,IAAIC,IAC5BF,EAAKG,QAAQ,SAACC,EAAKC,GAAM,OAAAD,EAAIE,aAAaC,IAAI,SAAAX,GAAQ,MAAA,CAACA,EAAMS,EAAE,EAAC,IAGlE,MAAO,CACLG,KAAMvE,EAAKuE,KAEXC,MAAKA,SAASpC,GAAQ,IAAkBqC,IAAAA,EAAAC,EAmQrCvE,EAnQqCC,EAAAA,SAAAC,GAAA,IAAAsE,EAAAC,EAAAC,EAAAC,EAAA3E,GAAAA,EAAAE,OAAAA,EAuDtC,IAAI0E,EAAqB3C,EAAI4C,QAAQjE,IAAI,gBACrCkE,EAGoB,OAHTN,EACZO,MAAMC,QAAQJ,GACXA,EAAmBK,KAAK,KACxBL,GAAkBJ,OAAK5C,EACzBsD,EAAUjD,EAAI4C,QAAQjE,IAAI,WAE1BuE,EC5HqB,SAACC,GAC9B,GAAkC,iBAAvBA,EAAX,CAEA,IAAIC,EAAMD,EACPE,MAAM,KACNnB,IAAI,SAAAgB,GAAE,OAAIA,EAAGI,MAAM,GACnBC,OAAOC,SACV,OAAOJ,EAAIK,OAAS,EAAIL,EAAI,QAAKzD,CAN2B,CAO9D,CDoHe+D,CAG6B,OAHZlB,EAEaC,OAFbA,EACkBC,OADlBA,EACxB1C,EAAI4C,QAAQjE,IAAI,4BAA0B+D,EACxC1C,EAAI4C,QAAQjE,IAAI,qBAAmB8D,EACnCzC,EAAI4C,QAAQjE,IAAI,oBAAkB6D,EAClCxC,EAAI4C,QAAQjE,IAAI,cAGhBiE,EAAU,IAAIe,QAElB,GAAIC,EACF,IAAA,IAAAC,EAAA,EAAAC,EAAyBC,OAAOC,QAAQC,GAAYJ,EAAAC,EAAAL,OAAAI,IAAE,CAAjD,IAAAK,EAAAJ,EAAAD,GACHjB,EAAQuB,OADGD,EAAE7H,GAAK6H,EAClBtB,GACF,CACD,OAAAtE,QAAAC,QAEYyC,EAAOoD,mBAAkB,WAAA,IAAA,OAAA9F,QAAAC,QAE5ByC,EAAOqD,cACX,CAAExB,YAAAA,EAAaI,QAAAA,GAASqB,WAAAA,IAAAA,IAAAA,EAAAC,EAAAjG,OAAAA,QAAAC,QAEhByC,EAAOwD,UACX,CACEjD,KAAM,cACNkD,GAAI,aACJC,WAAY,CACVxB,GAAAA,EACAyB,UAAW,OACXC,GAAiC,OAA/BN,EAAEtE,EAAI4C,QAAQjE,IAAI,eAAa2F,EAAI,GACrCO,OAAiC,OAA3BN,EAAEvE,EAAI4C,QAAQjE,IAAI,WAAS4F,EAAI,KAExC,WAAA,IAEC,QAAIO,EACEC,EAAyC,GACzC1D,EAAK2D,EAAiB,QAEtBC,EAAeC,EAAK,WAAAC,IAAAA,EACtB,OAAAC,EAAOC,MAA+B,OAA1BF,EAACnF,EAAI4C,QAAQjE,IAAI,WAASwG,EAAI,GAAG,GAG3CG,EAA0B,CAC5BC,IAAKvF,EAAIuF,IACT3C,QAAS5C,EAAI4C,QACb4C,MAAOD,EAAIE,aACXrF,KAAAA,EACAsF,QAAStF,EACT8C,GAAAA,EACAyC,UAAWtE,EAEXuE,WAAY,WAAM,OAAAX,GAAc,EAChCY,UAAW,SAACtE,GAAiB,OAAA0D,IAAe1D,EAAK,EACjDuE,UAAW,SAACvE,EAAclF,EAAeuB,GACvC,IAAImI,EAASX,EAAOY,UAAUzE,EAAMlF,EAAOuB,GAE3CgF,EAAQuB,OAAO,aAAc4B,EAC/B,EAEAE,WAAY,SAACtI,GACXoH,EAAYlF,KAAKlC,EACnB,EAEAS,qBAAsB,IAAIyD,IAE1BqE,cAAe,SAACC,GACd,IAAAC,IAAAA,EAAAC,EAAAA,EAAyBtC,OAAOC,QAAQmC,GAAWC,EAAAC,EAAA5C,OAAA2C,IAAE,CAAhD,IAAAE,EAAAD,EAAAD,GAAKjI,EAAGmI,EAAEjK,GAAAA,EAAKiK,EAClB,GAAA,GAAIxD,MAAMC,QAAQ1G,GAChB,IAAA,IAAmBkK,EAAnBC,EAAAC,EAAcpK,KAAKkK,EAAAC,KAAAE,MAAE9D,EAAQuB,OAAOhG,EAA1BoI,EAAAlK,YAEVuG,EAAQuB,OAAOhG,EAAK9B,EAExB,CACF,GAcF,OAXA2E,EAAO2F,kBAAkBC,WAAW,cAAe,CACjDrB,IAAKvF,EAAIuF,IACTC,MAAOzB,OAAO8C,YAAYtB,EAAIE,aAAazB,aAG7ChD,EAAO2F,kBAAkBG,cAAc,CACrCC,SAAU,wBACVC,KAAM5G,EACN6G,YAAa,qBAGf3I,QAAAC,QAAO2I,EACLC,EAAuB,CACrBC,KAAM,UACNC,UAAWhG,EACX6B,GAAIA,MAAAA,EAAAA,EAAM,UACVoE,UAAwCxC,OAA/BA,EAAE9E,EAAI4C,QAAQjE,IAAI,eAAamG,EAAI,KAEnC,WAAA,IACT,IAAIyC,EAAa,IAAI1F,IAKjB2F,EAAS,CACXpH,KAAM,CACJqH,WAAY,eACZtG,MAAO,IAETuG,OAAQ,KAGNC,EAAYpC,EAAIqC,SAASvE,MAAM,KAAKE,OAAOC,SAC3CqE,EAAWF,EAAUA,EAAUlE,OAAS,GAE5C,GAAmB,KAAfoE,EAAS,GAAW,CAAAC,IAAAA,EAClBzG,EAAKwG,EAASE,MAAM,GACpBC,EAAWpG,EAAoBjD,IAAI0C,GACvC,GAAgB1B,MAAZqI,EACF,OAAA1J,QAAAC,QAAO,IAAI0J,SACTC,KAAKC,UACHC,EAAc,CAAExH,OAAQ,YAAayH,cAEvC,CAAEX,OAAQ,IAAK9E,QAAAA,KAInB,IAAIzB,EAAgC2G,OAA3BA,EAAGP,EAAW5I,IAAIqJ,IAASF,EAAI,GACxC3G,EAAMtB,KAAK,CACTwB,GAAI2D,EAAiB,SACrBzD,KAAMF,EACNG,QAASpB,IAEXmH,EAAWlJ,IAAI2J,EAAU7G,EAC3B,KAAO,CACL,IAAIb,EAASR,EAAWS,SAASH,GACjC,IAAKE,EAAOE,QACV,OAAAlC,QAAAC,QAAO,IAAI0J,SACTC,KAAKC,UACHzH,EAAgB,CACdC,OAAQL,EAAOK,OACfC,OAAQ,iBACPyH,cAEL,CAAEX,OAAQ,IAAK9E,QAAAA,KAInB,IAAA0F,IAAmCC,EAAnCD,EAAA7B,EAAiBnG,EAAOjE,MAAM8E,SAAKoH,EAAAD,KAAA5B,MAAE,CAAA,IAAA8B,EAA5BC,EAAIF,EAAAlM,MACP2L,EAAWpG,EAAoBjD,IAAI8J,EAAKlH,MAC5C,GAAgB5B,MAAZqI,EACF,OAAA1J,QAAAC,QAAO,IAAI0J,SACTC,KAAKC,UACHC,EAAc,CAAExH,OAAQ,YAAayH,cAEvC,CAAEX,OAAQ,IAAK9E,QAAAA,KAInB,IAAIzB,EAAgC,OAA3BqH,EAAGjB,EAAW5I,IAAIqJ,IAASQ,EAAI,GACxCrH,EAAMtB,KAAK4I,GACXlB,EAAWlJ,IAAI2J,EAAU7G,EAC3B,CACF,CAAC,OAAA7C,QAAAC,QAEKD,QAAQoK,IACZ5F,MAAM6F,KAAKpB,EAAWvD,WAAW9B,IAAG,SAAA0G,GAAA,IAASZ,EAAQY,EAAEzH,GAAAA,EAAKyH,SACjC,OAAAtK,QAAAC,QAAfoD,EAAKqG,GACKa,QAAQvD,EAAS,CACnCK,UAAWtE,EACXF,MAAAA,KACAxE,KAHEuB,SAAAA,GAAG4K,IAAAA,EAKPtB,EAAOE,OAASqB,KAAKC,IAAIxB,EAAOE,OAAQxJ,EAAIwJ,SAC5CoB,EAAAtB,EAAOpH,KAAKe,OAAMtB,KAAIoJ,MAAAH,EAAI5K,EAAIkC,KAAKe,MAAO,EAC5C,CAAC,MAAAhE,GAAA,OAAAmB,QAAAO,OAAA1B,EAAA,CAAA,KACFR,KAAA,WAI+C,OAFhDiG,EAAQuB,OAAO,WAAY9C,GAC3BuB,EAAQuB,OAAO,eAAgB,wBAC/BvB,EAAQuB,OAAO,eAAgB,iBAAiB7F,QAAAC,QAE1CD,QAAQoK,IAAI3D,EAAY7C,IAAI,SAAA5F,GAAC,OAAIA,GAAG,KAAEK,KAE5C,WAAA,OAAW,IAAAsL,SAASjC,EAAUkD,OAAO1B,EAAOpH,MAAO,CACjDsH,OAAQF,EAAOE,OACf9E,QAAAA,GACC,EAAA,EACL,CAAC,MAAAzF,GAAA,OAAAmB,QAAAO,OAAA1B,EAAA,CAAA,GAEL,CAAE,MAAOA,GAKP,OAJAgM,QAAQC,MAAMjM,GAEd6D,EAAOqI,iBAAiBlM,GAExBmB,QAAAC,QAAO,IAAI0J,SAASC,KAAKC,UAAUmB,IAAsBjB,cAAe,CACtEX,OAAQ,IACR9E,QAAAA,IAEJ,CACF,CAAC,MAAAzF,GAAA,OAAAmB,QAAAO,OAAA1B,EACF,CAAA,GAAA,CAAA,MAAAA,GAAA,OAAAmB,QAAAO,OAAA1B,EAAA,CAAA,GACJA,CAAAA,MAAAA,GAAAmB,OAAAA,QAAAO,OAAA1B,EACJ,CAAA,GAAA,EAlQG0H,EAAkC,OAA5BxC,EAAGrC,EAAI4C,QAAQjE,IAAI,WAAS0D,EAAI,GACtCuB,GAAS,EAEb,GAAIhG,EAAK2L,MAAQ,YAAa3L,EAAK2L,KACjC,IACE,IACIC,EADM,IAAIC,IAAI5E,GACG6E,SAASrG,MAAM,KAAK0E,OAAO,GAAG/E,KAAK,KACxDY,EAAShG,EAAK2L,KAAKI,QAAQC,SAASJ,EACtC,CAAE,MAAOrM,GAAG,MAGHS,EAAK2L,MAAQ,UAAW3L,EAAK2L,OACtC3F,EAAShG,EAAK2L,KAAKM,MAAMhF,IAG3B,IAAIU,EAAM,IAAIkE,IAAIzJ,EAAIuF,KAElBuE,EAAiC,OAAZxH,EAAG1E,EAAK2L,OAALjH,OAASA,EAATA,EAAWM,cAAXN,EAAAA,EAAoBU,KAAK,MACjD8G,IAAuBA,GAA6BA,KAAAA,GAAwBxG,QAEhF,IAAIW,EAAsCL,EACtC,CACE,8BAA+BiB,EAC/B,+BAAgC,gBAChC,+BACEiF,sDAAAA,MAAAA,EAAAA,EAAyB,IAE3B,yBAA0B,SAC1B,mCAAoC,QAEtC,CAAA,EAEJ,GAAkB,WAAd9J,EAAI+J,OACN,OACEzL,QAAAC,QADEqF,EACK,IAAIqE,SAAS,KAAM,CACxBP,OAAQ,IACR9E,QAASqB,IAIN,IAAIgE,SAAS,KAAM,CAAEP,OAAQ,OAGtC,IAAItH,EAAY,KAAK3B,sFAAAuL,CAAA,WAEjBC,IAAAA,EACKjE,EAAUkE,OAAM5L,OAAAA,QAAAC,QAAOyB,EAAImK,QAAMxN,KAAA,SAAAyN,GAAxChK,EAAI6J,EAAAxB,KAAGzC,EAASoE,EAA0B,EAC5C,EAAY,WAAA,IAAAC,EACH,IAAIpC,SACTC,KAAKC,UAAUmC,EAAmB,CAAEC,QAAS,iBAAkBlC,cAC/D,CAAEX,OAAQ,MACX2C,OAAAtM,EAAAsM,EAAAA,CACH,GAAC,OAAA/L,QAAAC,QAAAE,GAAAA,EAAA9B,KAAA8B,EAAA9B,KAAAqB,GAAAA,EAAAS,GA+MH,CAAC,MAAAtB,GAAAmB,OAAAA,QAAAO,OAAA1B,KAEL,EEhUI6D,EAASC,IAEFuJ,EACT,SAAC5M,GAeA,OACA0B,SAAAA,GACC,IAcImL,EAA2B,SAACnL,GAC9B,OAAAyE,OAAOC,QAAQ1E,GAAYwC,QAAQ,SAAAS,GAAE,IAAApE,EAAGoE,KAAElG,EAAKkG,EAC7C,GAAA,OAAIlG,aAAiBgD,EAAgB,CAAClB,GAClB,iBAAT9B,EACFoO,EAAyBpO,GAAO6F,IAAI,SAAAX,GAAI,OAAOpD,MAAOoD,CAAI,GAC5D,EACT,EAAE,EAwHJ,MAAO,CACLU,aAvHiBwI,EAAyBnL,GAwH1CuJ,iBAnDA7I,EACAI,GAWG,IAAA,OAAA9B,QAAAC,QACiBD,QAAQoK,IAC1BtI,EAAKe,MAAMe,IAAWuG,SAAAA,EAAMzG,GAAC,WAAI1D,QAAAC,QAjFjC,SACFyB,EACAyI,EACAiC,GAKG,IACH,IAAIpF,EAAOnF,EAAA,CAAA,EAAQH,EAAKI,CAAAA,KAAMqI,EAAKjH,UAAU,OAAAlD,QAAAC,iCAGvCZ,EApCU,SAAC4D,GAIjB,IAHA,IAAIoJ,EAAQpJ,EAAK8B,MAAM,KACnBuH,EAAUtL,EAEPsL,GAAWD,EAAMlH,OAAS,GAE/B,KADAmH,EAAUA,EAAQD,EAAME,UACV,OAChB,KAEA,OAAID,GAAWA,aAAmBvL,EAAgBuL,EAGpD,IAAA,CAwBkBE,CAAYrC,EAAKlH,OAEnBjD,QAAAC,QAQSZ,EAAQoC,IAAIuF,EAAS,KAAG3I,cAAzC0D,GAEJ,MAAO,CACLqH,OAAQ,IACRpC,QAAStF,EACTK,SAAUA,EAASA,SACnB,GAbO,CACLiF,QAAAA,EACAoC,OAAQ,IACRrH,SAAU+H,EAAc,CAAExH,OAAQ,YAAayH,mCAPjD,IACE1K,sCAHuCqM,CAEzC,EAkBK7M,SAAAA,GAGP,OAFAgM,QAAQC,MAAMjM,GAEV4N,EAAe5N,IACbA,EAAE6J,KAAKU,QAAU,KACnB1G,EAAOqI,iBAAiBlM,EAAG,CACzB6N,KAAM,CAAEN,MAAAA,KAIL,CACLpF,QAAAA,EACAoC,OAAQvK,EAAE6J,KAAKU,OACfrH,SAAUlD,EAAEkL,gBAIhBrH,EAAOqI,iBAAiBlM,EAAG,CACzB6N,KAAM,CAAEN,MAAAA,KAGE,MAAZ9M,EAAKqN,SAALrN,EAAKqN,QAAU,CACbC,SAAUzC,EAAKlH,KACf4J,OAAQ1C,EAAKpH,GACbiE,QAAStF,EACToJ,MAAOjM,EACPuN,MAAAA,IAGK,CACLpF,QAAAA,EACAoC,OAAQ,IACRrH,SAAUiJ,IAAsBjB,cAEpC,GACF,CAAC,MAAAlL,GAAAmB,OAAAA,QAAAO,OAAA1B,EAAA,CAAA,CAkBqB4C,CAAIC,EAAKyI,EAAarI,EAAKuF,YAAUhJ,cAAjDuB,GAEJ,IACgB,MAAdN,EAAKwN,WAALxN,EAAKwN,UAAY,CACfV,MAAOtK,EAAKuF,UACZwF,OAAQ1C,EAAKpH,GACb6J,SAAUzC,EAAKlH,KACf+D,QAASpH,EAAIoH,QACbjF,SAAU,CAAEqH,OAAQxJ,EAAIwJ,OAAQtH,KAAMlC,EAAImC,WAE9C,CAAE,MAAOlD,GACP6D,EAAOqI,iBAAiBlM,GACxBgM,QAAQC,MAAMjM,EAChB,CAEA,MAAO,CACLsK,WAAY,oBACZpG,GAAIoH,EAAKpH,GACTE,KAAMkH,EAAKlH,KACXmG,OAAQxJ,EAAIwJ,OACZ1K,OAAQkB,EAAImC,SACZ,EACJ,CAAC,MAAAlD,UAAAmB,QAAAO,OAAA1B,QACFR,KAzBG0O,SAAAA,GA2BJ,MAAO,CACL3D,OAAQqB,KAAKC,IAAGC,MAARF,KAAYsC,EAAQnJ,IAAI,SAAAoJ,GAAC,OAAIA,EAAE5D,MAAM,IAC7CtH,KAAM,CACJqH,WAAY,eACZtG,MAAOkK,GAET,EACJ,CAAC,MAAAlO,GAAA,OAAAmB,QAAAO,OAAA1B,EAAA,CAAA,EAyCH,CAAC"}
1
+ {"version":3,"file":"index.module.js","sources":["../src/controller.ts","../src/rpcMux.ts","../src/extractIp.ts","../src/server.ts"],"sourcesContent":["import { ServiceError, validationError } from '@lowerdeck/error';\nimport { ValidationType } from '@lowerdeck/validation';\nimport * as Cookie from 'cookie';\n\nexport type Method = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\nexport interface ServiceRequest {\n query: URLSearchParams;\n headers: Headers;\n url: string;\n ip?: string;\n body: any;\n rawBody: any;\n requestId: string;\n\n getCookies: () => Record<string, string | undefined>;\n getCookie: (name: string) => string | undefined;\n setCookie: (name: string, value: string, opts?: Cookie.SerializeOptions) => void;\n\n sharedMiddlewareMemo: Map<string, Promise<any>>;\n beforeSend: (handler: () => Promise<any>) => void;\n appendHeaders: (headers: Record<string, string | string[]>) => void;\n}\n\nexport type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};\nexport type ExtendContext<C extends object, E> = E extends object ? Simplify<C & E> : C;\n\nexport class Group<Context extends { [key: string]: any } = {}> {\n constructor(\n private _middleware: Array<(ctx: Context & ServiceRequest) => Promise<any>> = []\n ) {}\n\n use<T extends { [key: string]: any } | undefined | void>(\n handler: (ctx: Context & ServiceRequest) => Promise<T>,\n opts?: {\n getSharedMemoKey?: (ctx: Context & ServiceRequest) => string;\n }\n ) {\n let middleware = async (ctx: Parameters<typeof handler>[0]): Promise<T> => {\n let key = opts?.getSharedMemoKey?.(ctx);\n if (key && ctx.sharedMiddlewareMemo.has(key)) {\n return await ctx.sharedMiddlewareMemo.get(key)!;\n }\n\n let res = handler(ctx);\n if (key) ctx.sharedMiddlewareMemo.set(key, res);\n\n return await res;\n };\n\n return new Group<Simplify<Context & T>>([...this._middleware, middleware]);\n }\n\n createMiddleware<T extends { [key: string]: any }, P = void>(\n handler: (ctx: Context & ServiceRequest, input: P) => Promise<T>,\n opts?: {\n getSharedMemoKey?: (ctx: Context & ServiceRequest, input: P) => string;\n }\n ) {\n return (input: P) =>\n async (ctx: Context & ServiceRequest): Promise<T> => {\n let key = opts?.getSharedMemoKey?.(ctx, input);\n if (key && ctx.sharedMiddlewareMemo.has(key)) {\n return await ctx.sharedMiddlewareMemo.get(key)!;\n }\n\n let res = handler(ctx, input);\n if (key) ctx.sharedMiddlewareMemo.set(key, res);\n\n return await res;\n };\n }\n\n handler() {\n return new Handler([...this._middleware]);\n }\n\n controller<\n HandlersAndSubControllers extends {\n [key: string]: Handler<any, any, any> | Controller<any>;\n }\n >(handlers: HandlersAndSubControllers): Controller<HandlersAndSubControllers> {\n return handlers;\n }\n}\n\nexport type Controller<\n HandlersAndSubControllers extends { [key: string]: Handler<any, any, any> | Controller<any> }\n> = HandlersAndSubControllers;\n\nexport type InferControllerType<T> = T extends Controller<infer U> ? U : never;\n\nexport type InferClient<\n HandlersAndSubControllers extends { [key: string]: Handler<any, any, any> | Controller<any> }\n> = {\n [K in keyof HandlersAndSubControllers]: HandlersAndSubControllers[K] extends Handler<\n infer I,\n infer O,\n infer C\n >\n ? ((\n input: I,\n opts?: { headers?: Record<string, string>; query?: Record<string, string> }\n ) => Promise<O>) & {\n getFull: (\n input: I,\n opts?: { headers?: Record<string, string>; query?: Record<string, string> }\n ) => Promise<{\n data: O;\n status: number;\n headers: Record<string, string>;\n }>;\n }\n : HandlersAndSubControllers[K] extends Controller<infer U>\n ? InferClient<U>\n : never;\n};\n\nexport class Handler<Input, Output, Context extends { [key: string]: any } = {}> {\n private _handler!: (\n ctx: Context & Omit<ServiceRequest, 'body'> & { input: Input }\n ) => Promise<Output>;\n private _validation: ValidationType<Input> | undefined;\n\n constructor(\n private _middleware: Array<(ctx: Context & ServiceRequest) => Promise<any>> = []\n ) {}\n\n do<HandlerOutput>(\n handler: (\n ctx: Context & Omit<ServiceRequest, 'body'> & { input: Input }\n ) => Promise<HandlerOutput>\n ) {\n if (this._handler != undefined) throw new Error('Handler already defined');\n\n // @ts-ignore\n this._handler = handler;\n\n return this as any as Handler<Input, HandlerOutput, Context>;\n }\n\n use<T extends { [key: string]: any } = {}>(\n handler: (ctx: Context & ServiceRequest) => Promise<T | undefined | void>\n ) {\n this._middleware.push(handler);\n return this as any as Handler<Input, Output, ExtendContext<Context, T>>;\n }\n\n input<HandlerInput>(validation: ValidationType<HandlerInput>) {\n if (this._validation != undefined) throw new Error('Input validation already defined');\n\n // @ts-ignore\n this._validation = validation;\n\n return this as any as Handler<HandlerInput, Output, Context>;\n }\n\n async run(\n req: ServiceRequest,\n initialContext: any\n ): Promise<{\n response: Output;\n }> {\n if (!this._handler) throw new Error('Handler not defined');\n\n let input = req.body as Input;\n\n if (this._validation) {\n let valRes = this._validation.validate(req.body);\n\n if (!valRes.success) {\n throw new ServiceError(\n validationError({ errors: valRes.errors, entity: 'call_data' })\n );\n }\n\n input = valRes.value;\n }\n\n let ctx = {\n ...initialContext,\n ...req,\n\n // Always use the sanitized input\n body: input\n };\n\n for (let mw of this._middleware) {\n let res = await mw(ctx);\n if (res) ctx = { ...ctx, ...res };\n }\n\n let res = await this._handler({\n ...ctx,\n input,\n body: undefined\n });\n\n return {\n response: res\n };\n }\n}\n","import {\n internalServerError,\n notAcceptableError,\n notFoundError,\n validationError\n} from '@lowerdeck/error';\nimport { createExecutionContext, provideExecutionContext } from '@lowerdeck/execution-context';\nimport { generateCustomId } from '@lowerdeck/id';\nimport { memo } from '@lowerdeck/memo';\nimport { getSentry } from '@lowerdeck/sentry';\nimport { serialize } from '@lowerdeck/serialize';\nimport { v } from '@lowerdeck/validation';\nimport * as Cookie from 'cookie';\nimport { ServiceRequest } from './controller';\nimport { parseForwardedFor } from './extractIp';\n\nlet Sentry = getSentry();\n\nlet validation = v.object({\n calls: v.array(\n v.object({\n id: v.string(),\n name: v.string(),\n payload: v.any()\n })\n )\n});\n\nexport let rpcMux = (\n opts: {\n path: string;\n cors?: {\n headers?: string[];\n } & ({ domains: string[] } | { check: (origin: string) => boolean });\n },\n rpcs: {\n handlerNames: string[];\n runMany: (\n req: ServiceRequest,\n body: {\n requestId: string;\n calls: {\n id: string;\n name: string;\n payload: any;\n }[];\n }\n ) => Promise<{\n status: number;\n body: {\n calls: any[];\n };\n }>;\n }[]\n) => {\n let handlerNameToRpcMap = new Map<string, number>(\n rpcs.flatMap((rpc, i) => rpc.handlerNames.map(name => [name, i]))\n );\n\n return {\n path: opts.path,\n\n fetch: async (req: any): Promise<any> => {\n let origin = req.headers.get('origin') ?? '';\n let corsOk = false;\n\n if (opts.cors && 'domains' in opts.cors) {\n try {\n let url = new URL(origin);\n let rootDomain = url.hostname.split('.').slice(-2).join('.');\n corsOk = opts.cors.domains.includes(rootDomain);\n } catch (e) {\n // Ignore -> no cors\n }\n } else if (opts.cors && 'check' in opts.cors) {\n corsOk = opts.cors.check(origin);\n }\n\n let url = new URL(req.url);\n\n let additionalCorsHeaders = opts.cors?.headers?.join(', ');\n if (additionalCorsHeaders) additionalCorsHeaders = `, ${additionalCorsHeaders}`.trim();\n\n let corsHeaders: Record<string, string> = corsOk\n ? {\n 'access-control-allow-origin': origin,\n 'access-control-allow-methods': 'POST, OPTIONS',\n 'access-control-allow-headers': `Content-Type, Authorization, Baggage, Sentry-Trace${\n additionalCorsHeaders ?? ''\n }`,\n 'access-control-max-age': '604800',\n 'access-control-allow-credentials': 'true'\n }\n : {};\n\n if (req.method == 'OPTIONS') {\n if (corsOk) {\n return new Response(null, {\n status: 204,\n headers: corsHeaders\n });\n }\n\n return new Response(null, { status: 403 });\n }\n\n let body: any = null;\n\n try {\n body = serialize.decode(await req.text());\n } catch (e) {\n return new Response(\n JSON.stringify(notAcceptableError({ message: 'Invalid JSON' }).toResponse()),\n { status: 406 }\n );\n }\n\n let sentryTraceHeaders = req.headers.get('sentry-trace');\n let sentryTrace =\n (Array.isArray(sentryTraceHeaders)\n ? sentryTraceHeaders.join(',')\n : sentryTraceHeaders) ?? undefined;\n let baggage = req.headers.get('baggage');\n\n let ip = parseForwardedFor(\n req.headers.get('lowerdeck-connecting-ip') ??\n req.headers.get('cf-connecting-ip') ??\n req.headers.get('x-forwarded-for') ??\n req.headers.get('x-real-ip')\n );\n\n let headers = new Headers();\n\n if (corsOk) {\n for (let [key, value] of Object.entries(corsHeaders)) {\n headers.append(key, value);\n }\n }\n\n return await Sentry.withIsolationScope(\n async () =>\n await Sentry.continueTrace(\n { sentryTrace, baggage },\n async () =>\n await Sentry.startSpan(\n {\n name: 'rpc request',\n op: 'rpc.server',\n attributes: {\n ip,\n transport: 'http',\n ua: req.headers.get('user-agent') ?? '',\n origin: req.headers.get('origin') ?? ''\n }\n },\n async () => {\n try {\n let beforeSends: Array<() => Promise<any>> = [];\n let id = generateCustomId('req_');\n\n let parseCookies = memo(() =>\n Cookie.parse(req.headers.get('cookie') ?? '')\n );\n\n let request: ServiceRequest = {\n url: req.url,\n headers: req.headers,\n query: url.searchParams,\n body,\n rawBody: body,\n ip,\n requestId: id,\n\n getCookies: () => parseCookies(),\n getCookie: (name: string) => parseCookies()[name],\n setCookie: (name: string, value: string, opts?: any) => {\n let cookie = Cookie.serialize(name, value, opts);\n // @ts-ignore\n headers.append('Set-Cookie', cookie);\n },\n\n beforeSend: (handler: () => Promise<any>) => {\n beforeSends.push(handler);\n },\n\n sharedMiddlewareMemo: new Map<string, Promise<any>>(),\n\n appendHeaders: (newHeaders: Record<string, string | string[]>) => {\n for (let [key, value] of Object.entries(newHeaders)) {\n if (Array.isArray(value)) {\n for (let v of value) headers.append(key, v);\n } else {\n headers.append(key, value);\n }\n }\n }\n };\n\n Sentry.getCurrentScope().setContext('rpc.request', {\n url: req.url,\n query: Object.fromEntries(url.searchParams.entries())\n });\n\n Sentry.getCurrentScope().addAttachment({\n filename: 'rpc.request.body.json',\n data: body,\n contentType: 'application/json'\n });\n\n return provideExecutionContext(\n createExecutionContext({\n type: 'request',\n contextId: id,\n ip: ip ?? '0.0.0.0',\n userAgent: req.headers.get('user-agent') ?? ''\n }),\n async () => {\n let callsByRpc = new Map<\n number,\n { id: string; name: string; payload: any }[]\n >();\n\n let resRef = {\n body: {\n __typename: 'rpc.response',\n calls: [] as any[]\n },\n status: 200\n };\n\n let pathParts = url.pathname.split('/').filter(Boolean);\n let lastPart = pathParts[pathParts.length - 1];\n\n let isSingle = lastPart[0] == '$';\n\n if (isSingle) {\n let id = lastPart.slice(1);\n let rpcIndex = handlerNameToRpcMap.get(id);\n if (rpcIndex == undefined) {\n return new Response(\n JSON.stringify(\n notFoundError({ entity: 'handler' }).toResponse()\n ),\n { status: 404, headers }\n );\n }\n\n let calls = callsByRpc.get(rpcIndex) ?? [];\n calls.push({\n id: generateCustomId('call_'),\n name: id,\n payload: body\n });\n callsByRpc.set(rpcIndex, calls);\n } else {\n let valRes = validation.validate(body);\n if (!valRes.success) {\n return new Response(\n JSON.stringify(\n validationError({\n errors: valRes.errors,\n entity: 'request_data'\n }).toResponse()\n ),\n { status: 406, headers }\n );\n }\n\n for (let call of valRes.value.calls) {\n let rpcIndex = handlerNameToRpcMap.get(call.name);\n if (rpcIndex == undefined) {\n return new Response(\n JSON.stringify(\n notFoundError({ entity: 'handler' }).toResponse()\n ),\n { status: 404, headers }\n );\n }\n\n let calls = callsByRpc.get(rpcIndex) ?? [];\n calls.push(call as any);\n callsByRpc.set(rpcIndex, calls);\n }\n }\n\n await Promise.all(\n Array.from(callsByRpc.entries()).map(async ([rpcIndex, calls]) => {\n let rpc = rpcs[rpcIndex];\n let res = await rpc.runMany(request, {\n requestId: id,\n calls\n });\n\n resRef.status = Math.max(resRef.status, res.status);\n resRef.body.calls.push(...res.body.calls);\n })\n );\n\n headers.append('x-req-id', id);\n headers.append('content-type', 'application/rpc+json');\n headers.append('x-powered-by', 'lowerdeck RPC');\n\n await Promise.all(beforeSends.map(s => s()));\n\n return new Response(\n serialize.encode(\n isSingle ? resRef.body.calls[0].result : resRef.body\n ),\n {\n status: resRef.status,\n headers\n }\n );\n }\n );\n } catch (e) {\n console.error(e);\n\n Sentry.captureException(e);\n\n return new Response(JSON.stringify(internalServerError().toResponse()), {\n status: 500,\n headers\n });\n }\n }\n )\n )\n );\n }\n };\n};\n","export let parseForwardedFor = (xForwardedForHeader?: string | null | undefined) => {\n if (typeof xForwardedForHeader != 'string') return undefined;\n\n let ips = xForwardedForHeader\n .split(',')\n .map(ip => ip.trim())\n .filter(Boolean);\n return ips.length > 0 ? ips[0] : undefined;\n};\n","import { internalServerError, isServiceError, notFoundError } from '@lowerdeck/error';\nimport { getSentry } from '@lowerdeck/sentry';\nimport { Controller, Handler, ServiceRequest } from './controller';\n\nlet Sentry = getSentry();\n\nexport let createServer =\n (opts: {\n onError?: (opts: {\n request: ServiceRequest;\n error: any;\n reqId: string;\n callId: string;\n callName: string;\n }) => void;\n onRequest?: (opts: {\n reqId: string;\n callId: string;\n callName: string;\n request: ServiceRequest;\n response: { status: number; body: any };\n }) => void;\n }) =>\n (controller: Controller<any>) => {\n let findHandler = (name: string): Handler<any, any, any> | null => {\n let parts = name.split(':');\n let current = controller;\n\n while (current && parts.length > 0) {\n current = current[parts.shift()!];\n if (!current) return null;\n }\n\n if (current && current instanceof Handler) return current;\n\n return null;\n };\n\n let getSupportedHandlerNames = (controller: Controller<any>): string[] =>\n Object.entries(controller).flatMap(([key, value]) => {\n if (value instanceof Handler) return [key];\n if (typeof value == 'object')\n return getSupportedHandlerNames(value).map(name => `${key}:${name}`);\n return [];\n });\n\n let handlerNames = getSupportedHandlerNames(controller);\n\n let run = async (\n req: ServiceRequest,\n call: { id: string; name: string; payload: any },\n reqId: string\n ): Promise<{\n response: any;\n status: number;\n request: ServiceRequest;\n }> => {\n let request = { ...req, body: call.payload };\n\n try {\n let handler = findHandler(call.name);\n\n if (!handler) {\n return {\n request,\n status: 404,\n response: notFoundError({ entity: 'handler' }).toResponse()\n };\n }\n\n let response = await handler.run(request, {});\n\n return {\n status: 200,\n request: req,\n response: response.response\n };\n } catch (e) {\n console.error(e);\n\n if (isServiceError(e)) {\n if (e.data.status >= 500) {\n Sentry.captureException(e, {\n tags: { reqId }\n });\n }\n\n return {\n request,\n status: e.data.status,\n response: e.toResponse()\n };\n }\n\n Sentry.captureException(e, {\n tags: { reqId }\n });\n\n opts.onError?.({\n callName: call.name,\n callId: call.id,\n request: req,\n error: e,\n reqId\n });\n\n return {\n request,\n status: 500,\n response: internalServerError().toResponse()\n };\n }\n };\n\n let runMany = async (\n req: ServiceRequest,\n body: {\n calls: {\n id: string;\n name: string;\n payload: any;\n }[];\n requestId: string;\n }\n ): Promise<{\n status: number;\n body: any;\n }> => {\n let callRes = await Promise.all(\n body.calls.map(async (call, i) => {\n let res = await run(req, call as any, body.requestId);\n\n try {\n opts.onRequest?.({\n reqId: body.requestId,\n callId: call.id,\n callName: call.name,\n request: res.request,\n response: { status: res.status, body: res.response }\n });\n } catch (e) {\n Sentry.captureException(e);\n console.error(e);\n }\n\n return {\n __typename: 'rpc.response.call',\n id: call.id,\n name: call.name,\n status: res.status,\n result: res.response\n };\n })\n );\n\n return {\n status: Math.max(...callRes.map(c => c.status)),\n body: {\n __typename: 'rpc.response',\n calls: callRes\n }\n };\n };\n\n return {\n handlerNames,\n runMany\n\n // fetch,\n\n // http: async (\n // req: IncomingMessage & {\n // body: any;\n // },\n // res: ServerResponse & { send: (body: any) => void }\n // ) => {\n // let headers = new Headers(\n // Object.fromEntries(\n // Object.entries(req.headers).map(([key, value]) => [\n // key,\n // value === undefined ? '' : String(value)\n // ])\n // )\n // );\n // let url = new URL(req.url ?? '', `http://${req.headers.host}`);\n\n // let request = new Request(url.toString(), {\n // method: req.method,\n // headers,\n // body: JSON.stringify(req.body)\n // });\n\n // let response = await fetch(request);\n\n // res.statusCode = response.status;\n\n // for (let [key, value] of response.headers.entries()) {\n // res.setHeader(key, value);\n // }\n\n // res.send(response.body);\n // }\n };\n };\n"],"names":["_settle","pact","state","value","s","_Pact","o","bind","v","then","observer","prototype","onFulfilled","onRejected","result","this","callback","e","_this","_isSettledPact","thenable","Group","_middleware","_proto","use","handler","opts","concat","ctx","_exit","_temp2","_result","res","key","sharedMiddlewareMemo","set","Promise","resolve","getSharedMemoKey","_temp","has","get","_await$ctx$sharedMidd","reject","createMiddleware","input","_exit2","_temp4","_result2","_temp3","_await$ctx$sharedMidd2","Handler","controller","handlers","_handler","_validation","_proto2","undefined","Error","push","validation","run","req","initialContext","_temp6","_extends","body","response","valRes","validate","success","ServiceError","validationError","errors","entity","_temp5","_forOf","mw","Sentry","getSentry","object","calls","array","id","string","name","payload","any","rpcMux","rpcs","handlerNameToRpcMap","Map","flatMap","rpc","i","handlerNames","map","path","fetch","_req$headers$get6","_opts$cors","_ref","_ref2","_ref3","_req$headers$get","sentryTraceHeaders","headers","sentryTrace","Array","isArray","join","baggage","ip","xForwardedForHeader","ips","split","trim","filter","Boolean","length","parseForwardedFor","Headers","corsOk","_i","_Object$entries","Object","entries","corsHeaders","_Object$entries$_i","append","withIsolationScope","continueTrace","_req$headers$get2","_req$headers$get3","startSpan","op","attributes","transport","ua","origin","_req$headers$get5","beforeSends","generateCustomId","parseCookies","memo","_req$headers$get4","Cookie","parse","request","url","query","searchParams","rawBody","requestId","getCookies","getCookie","setCookie","cookie","serialize","beforeSend","appendHeaders","newHeaders","_i2","_Object$entries2","_Object$entries2$_i","_iterator","_step","_createForOfIteratorHelperLoose","done","getCurrentScope","setContext","fromEntries","addAttachment","filename","data","contentType","provideExecutionContext","createExecutionContext","type","contextId","userAgent","callsByRpc","resRef","__typename","status","pathParts","pathname","lastPart","isSingle","_callsByRpc$get","slice","rpcIndex","Response","JSON","stringify","notFoundError","toResponse","_iterator2","_step2","_callsByRpc$get2","call","all","from","_ref4","runMany","_resRef$body$calls","Math","max","apply","encode","console","error","captureException","internalServerError","cors","rootDomain","URL","hostname","domains","includes","check","additionalCorsHeaders","method","_catch","_decode","decode","text","_req$text","_Response","notAcceptableError","message","createServer","getSupportedHandlerNames","reqId","parts","current","shift","findHandler","isServiceError","tags","onError","callName","callId","onRequest","callRes","c"],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("@lowerdeck/error"),require("@lowerdeck/execution-context"),require("@lowerdeck/id"),require("@lowerdeck/memo"),require("@lowerdeck/sentry"),require("@lowerdeck/serialize"),require("@lowerdeck/validation"),require("cookie")):"function"==typeof define&&define.amd?define(["exports","@lowerdeck/error","@lowerdeck/execution-context","@lowerdeck/id","@lowerdeck/memo","@lowerdeck/sentry","@lowerdeck/serialize","@lowerdeck/validation","cookie"],r):r((e||self).rpcServer={},e.error,e.executionContext,e.id,e.memo,e.sentry,e.serialize,e.validation$1,e.cookie)}(this,function(e,r,t,n,o,i,a,s,u){function c(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach(function(t){if("default"!==t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})}}),r.default=e,r}var l=/*#__PURE__*/c(u);function d(e,r){(null==r||r>e.length)&&(r=e.length);for(var t=0,n=Array(r);t<r;t++)n[t]=e[t];return n}function f(e,r){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,r){if(e){if("string"==typeof e)return d(e,r);var t={}.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?d(e,r):void 0}}(e))||r&&e&&"number"==typeof e.length){t&&(e=t);var n=0;return function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function h(){return h=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)({}).hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e},h.apply(null,arguments)}const p="undefined"!=typeof Symbol?Symbol.iterator||(Symbol.iterator=Symbol("Symbol.iterator")):"@@iterator";function v(e,r,t){if(!e.s){if(t instanceof m){if(!t.s)return void(t.o=v.bind(null,e,r));1&r&&(r=t.s),t=t.v}if(t&&t.then)return void t.then(v.bind(null,e,r),v.bind(null,e,2));e.s=r,e.v=t;var n=e.o;n&&n(e)}}var m=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(r,t){var n=new e,o=this.s;if(o){var i=1&o?r:t;if(i){try{v(n,1,i(this.v))}catch(e){v(n,2,e)}return n}return this}return this.o=function(e){try{var o=e.v;1&e.s?v(n,1,r?r(o):o):t?v(n,1,t(o)):v(n,2,o)}catch(e){v(n,2,e)}},n},e}();function y(e){return e instanceof m&&1&e.s}var g=/*#__PURE__*/function(){function e(e){void 0===e&&(e=[]),this._middleware=void 0,this._middleware=e}var r=e.prototype;return r.use=function(r,t){return new e([].concat(this._middleware,[function(e){try{var n,o=function(t){if(n)return t;var o=r(e);return i&&e.sharedMiddlewareMemo.set(i,o),Promise.resolve(o)},i=null==t||null==t.getSharedMemoKey?void 0:t.getSharedMemoKey(e),a=function(){if(i&&e.sharedMiddlewareMemo.has(i))return Promise.resolve(e.sharedMiddlewareMemo.get(i)).then(function(e){return n=1,e})}();return Promise.resolve(a&&a.then?a.then(o):o(a))}catch(e){return Promise.reject(e)}}]))},r.createMiddleware=function(e,r){return function(t){return function(n){try{var o,i=function(r){if(o)return r;var i=e(n,t);return a&&n.sharedMiddlewareMemo.set(a,i),Promise.resolve(i)},a=null==r||null==r.getSharedMemoKey?void 0:r.getSharedMemoKey(n,t),s=function(){if(a&&n.sharedMiddlewareMemo.has(a))return Promise.resolve(n.sharedMiddlewareMemo.get(a)).then(function(e){return o=1,e})}();return Promise.resolve(s&&s.then?s.then(i):i(s))}catch(e){return Promise.reject(e)}}}},r.handler=function(){return new w([].concat(this._middleware))},r.controller=function(e){return e},e}(),w=/*#__PURE__*/function(){function e(e){void 0===e&&(e=[]),this._middleware=void 0,this._handler=void 0,this._validation=void 0,this._middleware=e}var t=e.prototype;return t.do=function(e){if(null!=this._handler)throw new Error("Handler already defined");return this._handler=e,this},t.use=function(e){return this._middleware.push(e),this},t.input=function(e){if(null!=this._validation)throw new Error("Input validation already defined");return this._validation=e,this},t.run=function(e,t){try{var n=function(){return Promise.resolve(o._handler(h({},s,{input:i,body:void 0}))).then(function(e){return{response:e}})},o=this;if(!o._handler)throw new Error("Handler not defined");var i=e.body;if(o._validation){var a=o._validation.validate(e.body);if(!a.success)throw new r.ServiceError(r.validationError({errors:a.errors,entity:"call_data"}));i=a.value}var s=h({},t,e,{body:i}),u=function(e,r){if("function"==typeof e[p]){var t,n,o,i=function(e){try{for(;!(t=a.next()).done;)if((e=r(t.value))&&e.then){if(!y(e))return void e.then(i,o||(o=v.bind(null,n=new m,2)));e=e.v}n?v(n,1,e):n=e}catch(e){v(n||(n=new m),2,e)}},a=e[p]();if(i(),a.return){var s=function(e){try{t.done||a.return()}catch(e){}return e};if(n&&n.then)return n.then(s,function(e){throw s(e)});s()}return n}if(!("length"in e))throw new TypeError("Object is not iterable");for(var u=[],c=0;c<e.length;c++)u.push(e[c]);return function(e,r){var t,n,o=-1;return function i(a){try{for(;++o<e.length;)if((a=r(o))&&a.then){if(!y(a))return void a.then(i,n||(n=v.bind(null,t=new m,2)));a=a.v}t?v(t,1,a):t=a}catch(e){v(t||(t=new m),2,e)}}(),t}(u,function(e){return r(u[e])})}(o._middleware,function(e){return Promise.resolve(e(s)).then(function(e){e&&(s=h({},s,e))})});return Promise.resolve(u&&u.then?u.then(n):n())}catch(e){return Promise.reject(e)}},e}(),b=i.getSentry(),P=s.v.object({calls:s.v.array(s.v.object({id:s.v.string(),name:s.v.string(),payload:s.v.any()}))}),S=i.getSentry();e.Group=g,e.Handler=w,e.createServer=function(e){return function(t){var n=function(e){return Object.entries(e).flatMap(function(e){var r=e[0],t=e[1];return t instanceof w?[r]:"object"==typeof t?n(t).map(function(e){return r+":"+e}):[]})};return{handlerNames:n(t),runMany:function(n,o){try{return Promise.resolve(Promise.all(o.calls.map(function(i,a){try{return Promise.resolve(function(n,o,i){try{var a=h({},n,{body:o.payload});return Promise.resolve(function(e,i){try{var s=(u=function(e){for(var r=e.split(":"),n=t;n&&r.length>0;)if(!(n=n[r.shift()]))return null;return n&&n instanceof w?n:null}(o.name))?Promise.resolve(u.run(a,{})).then(function(e){return{status:200,request:n,response:e.response}}):{request:a,status:404,response:r.notFoundError({entity:"handler"}).toResponse()}}catch(e){return i(e)}var u;return s&&s.then?s.then(void 0,i):s}(0,function(t){return console.error(t),r.isServiceError(t)?(t.data.status>=500&&S.captureException(t,{tags:{reqId:i}}),{request:a,status:t.data.status,response:t.toResponse()}):(S.captureException(t,{tags:{reqId:i}}),null==e.onError||e.onError({callName:o.name,callId:o.id,request:n,error:t,reqId:i}),{request:a,status:500,response:r.internalServerError().toResponse()})}))}catch(e){return Promise.reject(e)}}(n,i,o.requestId)).then(function(r){try{null==e.onRequest||e.onRequest({reqId:o.requestId,callId:i.id,callName:i.name,request:r.request,response:{status:r.status,body:r.response}})}catch(e){S.captureException(e),console.error(e)}return{__typename:"rpc.response.call",id:i.id,name:i.name,status:r.status,result:r.response}})}catch(e){return Promise.reject(e)}}))).then(function(e){return{status:Math.max.apply(Math,e.map(function(e){return e.status})),body:{__typename:"rpc.response",calls:e}}})}catch(e){return Promise.reject(e)}}}}},e.rpcMux=function(e,i){var s=new Map(i.flatMap(function(e,r){return e.handlerNames.map(function(e){return[e,r]})}));return{path:e.path,fetch:function(u){try{var c,d,h,p=function(e){var c,d,p,v;if(h)return e;var y=u.headers.get("sentry-trace"),w=null!=(c=Array.isArray(y)?y.join(","):y)?c:void 0,q=u.headers.get("baggage"),M=function(e){if("string"==typeof e){var r=e.split(",").map(function(e){return e.trim()}).filter(Boolean);return r.length>0?r[0]:void 0}}(null!=(d=null!=(p=null!=(v=u.headers.get("lowerdeck-connecting-ip"))?v:u.headers.get("cf-connecting-ip"))?p:u.headers.get("x-forwarded-for"))?d:u.headers.get("x-real-ip")),x=new Headers;if(m)for(var _=0,k=Object.entries(S);_<k.length;_++){var E=k[_];x.append(E[0],E[1])}return Promise.resolve(b.withIsolationScope(function(){try{return Promise.resolve(b.continueTrace({sentryTrace:w,baggage:q},function(){try{var e,c;return Promise.resolve(b.startSpan({name:"rpc request",op:"rpc.server",attributes:{ip:M,transport:"http",ua:null!=(e=u.headers.get("user-agent"))?e:"",origin:null!=(c=u.headers.get("origin"))?c:""}},function(){try{try{var e,c=[],d=n.generateCustomId("req_"),h=o.memo(function(){var e;return l.parse(null!=(e=u.headers.get("cookie"))?e:"")}),p={url:u.url,headers:u.headers,query:g.searchParams,body:j,rawBody:j,ip:M,requestId:d,getCookies:function(){return h()},getCookie:function(e){return h()[e]},setCookie:function(e,r,t){var n=l.serialize(e,r,t);x.append("Set-Cookie",n)},beforeSend:function(e){c.push(e)},sharedMiddlewareMemo:new Map,appendHeaders:function(e){for(var r=0,t=Object.entries(e);r<t.length;r++){var n=t[r],o=n[0],i=n[1];if(Array.isArray(i))for(var a,s=f(i);!(a=s()).done;)x.append(o,a.value);else x.append(o,i)}}};return b.getCurrentScope().setContext("rpc.request",{url:u.url,query:Object.fromEntries(g.searchParams.entries())}),b.getCurrentScope().addAttachment({filename:"rpc.request.body.json",data:j,contentType:"application/json"}),Promise.resolve(t.provideExecutionContext(t.createExecutionContext({type:"request",contextId:d,ip:null!=M?M:"0.0.0.0",userAgent:null!=(e=u.headers.get("user-agent"))?e:""}),function(){try{var e=new Map,t={body:{__typename:"rpc.response",calls:[]},status:200},o=g.pathname.split("/").filter(Boolean),u=o[o.length-1];if("$"==u[0]){var l,h=u.slice(1),v=s.get(h);if(null==v)return Promise.resolve(new Response(JSON.stringify(r.notFoundError({entity:"handler"}).toResponse()),{status:404,headers:x}));var m=null!=(l=e.get(v))?l:[];m.push({id:n.generateCustomId("call_"),name:h,payload:j}),e.set(v,m)}else{var y=P.validate(j);if(!y.success)return Promise.resolve(new Response(JSON.stringify(r.validationError({errors:y.errors,entity:"request_data"}).toResponse()),{status:406,headers:x}));for(var w,b=f(y.value.calls);!(w=b()).done;){var S,q=w.value,M=s.get(q.name);if(null==M)return Promise.resolve(new Response(JSON.stringify(r.notFoundError({entity:"handler"}).toResponse()),{status:404,headers:x}));var _=null!=(S=e.get(M))?S:[];_.push(q),e.set(M,_)}}return Promise.resolve(Promise.all(Array.from(e.entries()).map(function(e){var r=e[0],n=e[1];try{return Promise.resolve(i[r].runMany(p,{requestId:d,calls:n})).then(function(e){var r;t.status=Math.max(t.status,e.status),(r=t.body.calls).push.apply(r,e.body.calls)})}catch(e){return Promise.reject(e)}}))).then(function(){return x.append("x-req-id",d),x.append("content-type","application/rpc+json"),x.append("x-powered-by","lowerdeck RPC"),Promise.resolve(Promise.all(c.map(function(e){return e()}))).then(function(){return new Response(a.serialize.encode(t.body),{status:t.status,headers:x})})})}catch(e){return Promise.reject(e)}}))}catch(e){return console.error(e),b.captureException(e),Promise.resolve(new Response(JSON.stringify(r.internalServerError().toResponse()),{status:500,headers:x}))}}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}}))},v=null!=(c=u.headers.get("origin"))?c:"",m=!1;if(e.cors&&"domains"in e.cors)try{var y=new URL(v).hostname.split(".").slice(-2).join(".");m=e.cors.domains.includes(y)}catch(e){}else e.cors&&"check"in e.cors&&(m=e.cors.check(v));var g=new URL(u.url),w=null==(d=e.cors)||null==(d=d.headers)?void 0:d.join(", ");w&&(w=(", "+w).trim());var S=m?{"access-control-allow-origin":v,"access-control-allow-methods":"POST, OPTIONS","access-control-allow-headers":"Content-Type, Authorization, Baggage, Sentry-Trace"+(null!=w?w:""),"access-control-max-age":"604800","access-control-allow-credentials":"true"}:{};if("OPTIONS"==u.method)return Promise.resolve(m?new Response(null,{status:204,headers:S}):new Response(null,{status:403}));var j=null,q=function(e,r){try{var t=e()}catch(e){return r()}return t&&t.then?t.then(void 0,r):t}(function(){var e=a.serialize.decode;return Promise.resolve(u.text()).then(function(r){j=e.call(a.serialize,r)})},function(){var e=new Response(JSON.stringify(r.notAcceptableError({message:"Invalid JSON"}).toResponse()),{status:406});return h=1,e});return Promise.resolve(q&&q.then?q.then(p):p(q))}catch(e){return Promise.reject(e)}}}}});
1
+ !function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("@lowerdeck/error"),require("@lowerdeck/execution-context"),require("@lowerdeck/id"),require("@lowerdeck/memo"),require("@lowerdeck/sentry"),require("@lowerdeck/serialize"),require("@lowerdeck/validation"),require("cookie")):"function"==typeof define&&define.amd?define(["exports","@lowerdeck/error","@lowerdeck/execution-context","@lowerdeck/id","@lowerdeck/memo","@lowerdeck/sentry","@lowerdeck/serialize","@lowerdeck/validation","cookie"],r):r((e||self).rpcServer={},e.error,e.executionContext,e.id,e.memo,e.sentry,e.serialize,e.validation$1,e.cookie)}(this,function(e,r,t,n,o,i,a,s,u){function c(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach(function(t){if("default"!==t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})}}),r.default=e,r}var l=/*#__PURE__*/c(u);function d(e,r){(null==r||r>e.length)&&(r=e.length);for(var t=0,n=Array(r);t<r;t++)n[t]=e[t];return n}function f(e,r){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,r){if(e){if("string"==typeof e)return d(e,r);var t={}.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?d(e,r):void 0}}(e))||r&&e&&"number"==typeof e.length){t&&(e=t);var n=0;return function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function h(){return h=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)({}).hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e},h.apply(null,arguments)}const p="undefined"!=typeof Symbol?Symbol.iterator||(Symbol.iterator=Symbol("Symbol.iterator")):"@@iterator";function v(e,r,t){if(!e.s){if(t instanceof m){if(!t.s)return void(t.o=v.bind(null,e,r));1&r&&(r=t.s),t=t.v}if(t&&t.then)return void t.then(v.bind(null,e,r),v.bind(null,e,2));e.s=r,e.v=t;var n=e.o;n&&n(e)}}var m=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(r,t){var n=new e,o=this.s;if(o){var i=1&o?r:t;if(i){try{v(n,1,i(this.v))}catch(e){v(n,2,e)}return n}return this}return this.o=function(e){try{var o=e.v;1&e.s?v(n,1,r?r(o):o):t?v(n,1,t(o)):v(n,2,o)}catch(e){v(n,2,e)}},n},e}();function y(e){return e instanceof m&&1&e.s}var g=/*#__PURE__*/function(){function e(e){void 0===e&&(e=[]),this._middleware=void 0,this._middleware=e}var r=e.prototype;return r.use=function(r,t){return new e([].concat(this._middleware,[function(e){try{var n,o=function(t){if(n)return t;var o=r(e);return i&&e.sharedMiddlewareMemo.set(i,o),Promise.resolve(o)},i=null==t||null==t.getSharedMemoKey?void 0:t.getSharedMemoKey(e),a=function(){if(i&&e.sharedMiddlewareMemo.has(i))return Promise.resolve(e.sharedMiddlewareMemo.get(i)).then(function(e){return n=1,e})}();return Promise.resolve(a&&a.then?a.then(o):o(a))}catch(e){return Promise.reject(e)}}]))},r.createMiddleware=function(e,r){return function(t){return function(n){try{var o,i=function(r){if(o)return r;var i=e(n,t);return a&&n.sharedMiddlewareMemo.set(a,i),Promise.resolve(i)},a=null==r||null==r.getSharedMemoKey?void 0:r.getSharedMemoKey(n,t),s=function(){if(a&&n.sharedMiddlewareMemo.has(a))return Promise.resolve(n.sharedMiddlewareMemo.get(a)).then(function(e){return o=1,e})}();return Promise.resolve(s&&s.then?s.then(i):i(s))}catch(e){return Promise.reject(e)}}}},r.handler=function(){return new w([].concat(this._middleware))},r.controller=function(e){return e},e}(),w=/*#__PURE__*/function(){function e(e){void 0===e&&(e=[]),this._middleware=void 0,this._handler=void 0,this._validation=void 0,this._middleware=e}var t=e.prototype;return t.do=function(e){if(null!=this._handler)throw new Error("Handler already defined");return this._handler=e,this},t.use=function(e){return this._middleware.push(e),this},t.input=function(e){if(null!=this._validation)throw new Error("Input validation already defined");return this._validation=e,this},t.run=function(e,t){try{var n=function(){return Promise.resolve(o._handler(h({},s,{input:i,body:void 0}))).then(function(e){return{response:e}})},o=this;if(!o._handler)throw new Error("Handler not defined");var i=e.body;if(o._validation){var a=o._validation.validate(e.body);if(!a.success)throw new r.ServiceError(r.validationError({errors:a.errors,entity:"call_data"}));i=a.value}var s=h({},t,e,{body:i}),u=function(e,r){if("function"==typeof e[p]){var t,n,o,i=function(e){try{for(;!(t=a.next()).done;)if((e=r(t.value))&&e.then){if(!y(e))return void e.then(i,o||(o=v.bind(null,n=new m,2)));e=e.v}n?v(n,1,e):n=e}catch(e){v(n||(n=new m),2,e)}},a=e[p]();if(i(),a.return){var s=function(e){try{t.done||a.return()}catch(e){}return e};if(n&&n.then)return n.then(s,function(e){throw s(e)});s()}return n}if(!("length"in e))throw new TypeError("Object is not iterable");for(var u=[],c=0;c<e.length;c++)u.push(e[c]);return function(e,r){var t,n,o=-1;return function i(a){try{for(;++o<e.length;)if((a=r(o))&&a.then){if(!y(a))return void a.then(i,n||(n=v.bind(null,t=new m,2)));a=a.v}t?v(t,1,a):t=a}catch(e){v(t||(t=new m),2,e)}}(),t}(u,function(e){return r(u[e])})}(o._middleware,function(e){return Promise.resolve(e(s)).then(function(e){e&&(s=h({},s,e))})});return Promise.resolve(u&&u.then?u.then(n):n())}catch(e){return Promise.reject(e)}},e}(),b=i.getSentry(),P=s.v.object({calls:s.v.array(s.v.object({id:s.v.string(),name:s.v.string(),payload:s.v.any()}))}),S=i.getSentry();e.Group=g,e.Handler=w,e.createServer=function(e){return function(t){var n=function(e){return Object.entries(e).flatMap(function(e){var r=e[0],t=e[1];return t instanceof w?[r]:"object"==typeof t?n(t).map(function(e){return r+":"+e}):[]})};return{handlerNames:n(t),runMany:function(n,o){try{return Promise.resolve(Promise.all(o.calls.map(function(i,a){try{return Promise.resolve(function(n,o,i){try{var a=h({},n,{body:o.payload});return Promise.resolve(function(e,i){try{var s=(u=function(e){for(var r=e.split(":"),n=t;n&&r.length>0;)if(!(n=n[r.shift()]))return null;return n&&n instanceof w?n:null}(o.name))?Promise.resolve(u.run(a,{})).then(function(e){return{status:200,request:n,response:e.response}}):{request:a,status:404,response:r.notFoundError({entity:"handler"}).toResponse()}}catch(e){return i(e)}var u;return s&&s.then?s.then(void 0,i):s}(0,function(t){return console.error(t),r.isServiceError(t)?(t.data.status>=500&&S.captureException(t,{tags:{reqId:i}}),{request:a,status:t.data.status,response:t.toResponse()}):(S.captureException(t,{tags:{reqId:i}}),null==e.onError||e.onError({callName:o.name,callId:o.id,request:n,error:t,reqId:i}),{request:a,status:500,response:r.internalServerError().toResponse()})}))}catch(e){return Promise.reject(e)}}(n,i,o.requestId)).then(function(r){try{null==e.onRequest||e.onRequest({reqId:o.requestId,callId:i.id,callName:i.name,request:r.request,response:{status:r.status,body:r.response}})}catch(e){S.captureException(e),console.error(e)}return{__typename:"rpc.response.call",id:i.id,name:i.name,status:r.status,result:r.response}})}catch(e){return Promise.reject(e)}}))).then(function(e){return{status:Math.max.apply(Math,e.map(function(e){return e.status})),body:{__typename:"rpc.response",calls:e}}})}catch(e){return Promise.reject(e)}}}}},e.rpcMux=function(e,i){var s=new Map(i.flatMap(function(e,r){return e.handlerNames.map(function(e){return[e,r]})}));return{path:e.path,fetch:function(u){try{var c,d,h,p=function(e){var c,d,p,v;if(h)return e;var y=u.headers.get("sentry-trace"),w=null!=(c=Array.isArray(y)?y.join(","):y)?c:void 0,q=u.headers.get("baggage"),M=function(e){if("string"==typeof e){var r=e.split(",").map(function(e){return e.trim()}).filter(Boolean);return r.length>0?r[0]:void 0}}(null!=(d=null!=(p=null!=(v=u.headers.get("lowerdeck-connecting-ip"))?v:u.headers.get("cf-connecting-ip"))?p:u.headers.get("x-forwarded-for"))?d:u.headers.get("x-real-ip")),x=new Headers;if(m)for(var _=0,k=Object.entries(S);_<k.length;_++){var E=k[_];x.append(E[0],E[1])}return Promise.resolve(b.withIsolationScope(function(){try{return Promise.resolve(b.continueTrace({sentryTrace:w,baggage:q},function(){try{var e,c;return Promise.resolve(b.startSpan({name:"rpc request",op:"rpc.server",attributes:{ip:M,transport:"http",ua:null!=(e=u.headers.get("user-agent"))?e:"",origin:null!=(c=u.headers.get("origin"))?c:""}},function(){try{try{var e,c=[],d=n.generateCustomId("req_"),h=o.memo(function(){var e;return l.parse(null!=(e=u.headers.get("cookie"))?e:"")}),p={url:u.url,headers:u.headers,query:g.searchParams,body:j,rawBody:j,ip:M,requestId:d,getCookies:function(){return h()},getCookie:function(e){return h()[e]},setCookie:function(e,r,t){var n=l.serialize(e,r,t);x.append("Set-Cookie",n)},beforeSend:function(e){c.push(e)},sharedMiddlewareMemo:new Map,appendHeaders:function(e){for(var r=0,t=Object.entries(e);r<t.length;r++){var n=t[r],o=n[0],i=n[1];if(Array.isArray(i))for(var a,s=f(i);!(a=s()).done;)x.append(o,a.value);else x.append(o,i)}}};return b.getCurrentScope().setContext("rpc.request",{url:u.url,query:Object.fromEntries(g.searchParams.entries())}),b.getCurrentScope().addAttachment({filename:"rpc.request.body.json",data:j,contentType:"application/json"}),Promise.resolve(t.provideExecutionContext(t.createExecutionContext({type:"request",contextId:d,ip:null!=M?M:"0.0.0.0",userAgent:null!=(e=u.headers.get("user-agent"))?e:""}),function(){try{var e=new Map,t={body:{__typename:"rpc.response",calls:[]},status:200},o=g.pathname.split("/").filter(Boolean),u=o[o.length-1],l="$"==u[0];if(l){var h,v=u.slice(1),m=s.get(v);if(null==m)return Promise.resolve(new Response(JSON.stringify(r.notFoundError({entity:"handler"}).toResponse()),{status:404,headers:x}));var y=null!=(h=e.get(m))?h:[];y.push({id:n.generateCustomId("call_"),name:v,payload:j}),e.set(m,y)}else{var w=P.validate(j);if(!w.success)return Promise.resolve(new Response(JSON.stringify(r.validationError({errors:w.errors,entity:"request_data"}).toResponse()),{status:406,headers:x}));for(var b,S=f(w.value.calls);!(b=S()).done;){var q,M=b.value,_=s.get(M.name);if(null==_)return Promise.resolve(new Response(JSON.stringify(r.notFoundError({entity:"handler"}).toResponse()),{status:404,headers:x}));var k=null!=(q=e.get(_))?q:[];k.push(M),e.set(_,k)}}return Promise.resolve(Promise.all(Array.from(e.entries()).map(function(e){var r=e[0],n=e[1];try{return Promise.resolve(i[r].runMany(p,{requestId:d,calls:n})).then(function(e){var r;t.status=Math.max(t.status,e.status),(r=t.body.calls).push.apply(r,e.body.calls)})}catch(e){return Promise.reject(e)}}))).then(function(){return x.append("x-req-id",d),x.append("content-type","application/rpc+json"),x.append("x-powered-by","lowerdeck RPC"),Promise.resolve(Promise.all(c.map(function(e){return e()}))).then(function(){return new Response(a.serialize.encode(l?t.body.calls[0].result:t.body),{status:t.status,headers:x})})})}catch(e){return Promise.reject(e)}}))}catch(e){return console.error(e),b.captureException(e),Promise.resolve(new Response(JSON.stringify(r.internalServerError().toResponse()),{status:500,headers:x}))}}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}}))},v=null!=(c=u.headers.get("origin"))?c:"",m=!1;if(e.cors&&"domains"in e.cors)try{var y=new URL(v).hostname.split(".").slice(-2).join(".");m=e.cors.domains.includes(y)}catch(e){}else e.cors&&"check"in e.cors&&(m=e.cors.check(v));var g=new URL(u.url),w=null==(d=e.cors)||null==(d=d.headers)?void 0:d.join(", ");w&&(w=(", "+w).trim());var S=m?{"access-control-allow-origin":v,"access-control-allow-methods":"POST, OPTIONS","access-control-allow-headers":"Content-Type, Authorization, Baggage, Sentry-Trace"+(null!=w?w:""),"access-control-max-age":"604800","access-control-allow-credentials":"true"}:{};if("OPTIONS"==u.method)return Promise.resolve(m?new Response(null,{status:204,headers:S}):new Response(null,{status:403}));var j=null,q=function(e,r){try{var t=e()}catch(e){return r()}return t&&t.then?t.then(void 0,r):t}(function(){var e=a.serialize.decode;return Promise.resolve(u.text()).then(function(r){j=e.call(a.serialize,r)})},function(){var e=new Response(JSON.stringify(r.notAcceptableError({message:"Invalid JSON"}).toResponse()),{status:406});return h=1,e});return Promise.resolve(q&&q.then?q.then(p):p(q))}catch(e){return Promise.reject(e)}}}}});
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/controller.ts","../src/rpcMux.ts","../src/server.ts","../src/extractIp.ts"],"sourcesContent":["import { ServiceError, validationError } from '@lowerdeck/error';\nimport { ValidationType } from '@lowerdeck/validation';\nimport * as Cookie from 'cookie';\n\nexport type Method = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\nexport interface ServiceRequest {\n query: URLSearchParams;\n headers: Headers;\n url: string;\n ip?: string;\n body: any;\n rawBody: any;\n requestId: string;\n\n getCookies: () => Record<string, string | undefined>;\n getCookie: (name: string) => string | undefined;\n setCookie: (name: string, value: string, opts?: Cookie.SerializeOptions) => void;\n\n sharedMiddlewareMemo: Map<string, Promise<any>>;\n beforeSend: (handler: () => Promise<any>) => void;\n appendHeaders: (headers: Record<string, string | string[]>) => void;\n}\n\nexport type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};\nexport type ExtendContext<C extends object, E> = E extends object ? Simplify<C & E> : C;\n\nexport class Group<Context extends { [key: string]: any } = {}> {\n constructor(\n private _middleware: Array<(ctx: Context & ServiceRequest) => Promise<any>> = []\n ) {}\n\n use<T extends { [key: string]: any } | undefined | void>(\n handler: (ctx: Context & ServiceRequest) => Promise<T>,\n opts?: {\n getSharedMemoKey?: (ctx: Context & ServiceRequest) => string;\n }\n ) {\n let middleware = async (ctx: Parameters<typeof handler>[0]): Promise<T> => {\n let key = opts?.getSharedMemoKey?.(ctx);\n if (key && ctx.sharedMiddlewareMemo.has(key)) {\n return await ctx.sharedMiddlewareMemo.get(key)!;\n }\n\n let res = handler(ctx);\n if (key) ctx.sharedMiddlewareMemo.set(key, res);\n\n return await res;\n };\n\n return new Group<Simplify<Context & T>>([...this._middleware, middleware]);\n }\n\n createMiddleware<T extends { [key: string]: any }, P = void>(\n handler: (ctx: Context & ServiceRequest, input: P) => Promise<T>,\n opts?: {\n getSharedMemoKey?: (ctx: Context & ServiceRequest, input: P) => string;\n }\n ) {\n return (input: P) =>\n async (ctx: Context & ServiceRequest): Promise<T> => {\n let key = opts?.getSharedMemoKey?.(ctx, input);\n if (key && ctx.sharedMiddlewareMemo.has(key)) {\n return await ctx.sharedMiddlewareMemo.get(key)!;\n }\n\n let res = handler(ctx, input);\n if (key) ctx.sharedMiddlewareMemo.set(key, res);\n\n return await res;\n };\n }\n\n handler() {\n return new Handler([...this._middleware]);\n }\n\n controller<\n HandlersAndSubControllers extends {\n [key: string]: Handler<any, any, any> | Controller<any>;\n }\n >(handlers: HandlersAndSubControllers): Controller<HandlersAndSubControllers> {\n return handlers;\n }\n}\n\nexport type Controller<\n HandlersAndSubControllers extends { [key: string]: Handler<any, any, any> | Controller<any> }\n> = HandlersAndSubControllers;\n\nexport type InferControllerType<T> = T extends Controller<infer U> ? U : never;\n\nexport type InferClient<\n HandlersAndSubControllers extends { [key: string]: Handler<any, any, any> | Controller<any> }\n> = {\n [K in keyof HandlersAndSubControllers]: HandlersAndSubControllers[K] extends Handler<\n infer I,\n infer O,\n infer C\n >\n ? ((\n input: I,\n opts?: { headers?: Record<string, string>; query?: Record<string, string> }\n ) => Promise<O>) & {\n getFull: (\n input: I,\n opts?: { headers?: Record<string, string>; query?: Record<string, string> }\n ) => Promise<{\n data: O;\n status: number;\n headers: Record<string, string>;\n }>;\n }\n : HandlersAndSubControllers[K] extends Controller<infer U>\n ? InferClient<U>\n : never;\n};\n\nexport class Handler<Input, Output, Context extends { [key: string]: any } = {}> {\n private _handler!: (\n ctx: Context & Omit<ServiceRequest, 'body'> & { input: Input }\n ) => Promise<Output>;\n private _validation: ValidationType<Input> | undefined;\n\n constructor(\n private _middleware: Array<(ctx: Context & ServiceRequest) => Promise<any>> = []\n ) {}\n\n do<HandlerOutput>(\n handler: (\n ctx: Context & Omit<ServiceRequest, 'body'> & { input: Input }\n ) => Promise<HandlerOutput>\n ) {\n if (this._handler != undefined) throw new Error('Handler already defined');\n\n // @ts-ignore\n this._handler = handler;\n\n return this as any as Handler<Input, HandlerOutput, Context>;\n }\n\n use<T extends { [key: string]: any } = {}>(\n handler: (ctx: Context & ServiceRequest) => Promise<T | undefined | void>\n ) {\n this._middleware.push(handler);\n return this as any as Handler<Input, Output, ExtendContext<Context, T>>;\n }\n\n input<HandlerInput>(validation: ValidationType<HandlerInput>) {\n if (this._validation != undefined) throw new Error('Input validation already defined');\n\n // @ts-ignore\n this._validation = validation;\n\n return this as any as Handler<HandlerInput, Output, Context>;\n }\n\n async run(\n req: ServiceRequest,\n initialContext: any\n ): Promise<{\n response: Output;\n }> {\n if (!this._handler) throw new Error('Handler not defined');\n\n let input = req.body as Input;\n\n if (this._validation) {\n let valRes = this._validation.validate(req.body);\n\n if (!valRes.success) {\n throw new ServiceError(\n validationError({ errors: valRes.errors, entity: 'call_data' })\n );\n }\n\n input = valRes.value;\n }\n\n let ctx = {\n ...initialContext,\n ...req,\n\n // Always use the sanitized input\n body: input\n };\n\n for (let mw of this._middleware) {\n let res = await mw(ctx);\n if (res) ctx = { ...ctx, ...res };\n }\n\n let res = await this._handler({\n ...ctx,\n input,\n body: undefined\n });\n\n return {\n response: res\n };\n }\n}\n","import {\n internalServerError,\n notAcceptableError,\n notFoundError,\n validationError\n} from '@lowerdeck/error';\nimport { createExecutionContext, provideExecutionContext } from '@lowerdeck/execution-context';\nimport { generateCustomId } from '@lowerdeck/id';\nimport { memo } from '@lowerdeck/memo';\nimport { getSentry } from '@lowerdeck/sentry';\nimport { serialize } from '@lowerdeck/serialize';\nimport { v } from '@lowerdeck/validation';\nimport * as Cookie from 'cookie';\nimport { ServiceRequest } from './controller';\nimport { parseForwardedFor } from './extractIp';\n\nlet Sentry = getSentry();\n\nlet validation = v.object({\n calls: v.array(\n v.object({\n id: v.string(),\n name: v.string(),\n payload: v.any()\n })\n )\n});\n\nexport let rpcMux = (\n opts: {\n path: string;\n cors?: {\n headers?: string[];\n } & ({ domains: string[] } | { check: (origin: string) => boolean });\n },\n rpcs: {\n handlerNames: string[];\n runMany: (\n req: ServiceRequest,\n body: {\n requestId: string;\n calls: {\n id: string;\n name: string;\n payload: any;\n }[];\n }\n ) => Promise<{\n status: number;\n body: {\n calls: any[];\n };\n }>;\n }[]\n) => {\n let handlerNameToRpcMap = new Map<string, number>(\n rpcs.flatMap((rpc, i) => rpc.handlerNames.map(name => [name, i]))\n );\n\n return {\n path: opts.path,\n\n fetch: async (req: any): Promise<any> => {\n let origin = req.headers.get('origin') ?? '';\n let corsOk = false;\n\n if (opts.cors && 'domains' in opts.cors) {\n try {\n let url = new URL(origin);\n let rootDomain = url.hostname.split('.').slice(-2).join('.');\n corsOk = opts.cors.domains.includes(rootDomain);\n } catch (e) {\n // Ignore -> no cors\n }\n } else if (opts.cors && 'check' in opts.cors) {\n corsOk = opts.cors.check(origin);\n }\n\n let url = new URL(req.url);\n\n let additionalCorsHeaders = opts.cors?.headers?.join(', ');\n if (additionalCorsHeaders) additionalCorsHeaders = `, ${additionalCorsHeaders}`.trim();\n\n let corsHeaders: Record<string, string> = corsOk\n ? {\n 'access-control-allow-origin': origin,\n 'access-control-allow-methods': 'POST, OPTIONS',\n 'access-control-allow-headers': `Content-Type, Authorization, Baggage, Sentry-Trace${\n additionalCorsHeaders ?? ''\n }`,\n 'access-control-max-age': '604800',\n 'access-control-allow-credentials': 'true'\n }\n : {};\n\n if (req.method == 'OPTIONS') {\n if (corsOk) {\n return new Response(null, {\n status: 204,\n headers: corsHeaders\n });\n }\n\n return new Response(null, { status: 403 });\n }\n\n let body: any = null;\n\n try {\n body = serialize.decode(await req.text());\n } catch (e) {\n return new Response(\n JSON.stringify(notAcceptableError({ message: 'Invalid JSON' }).toResponse()),\n { status: 406 }\n );\n }\n\n let sentryTraceHeaders = req.headers.get('sentry-trace');\n let sentryTrace =\n (Array.isArray(sentryTraceHeaders)\n ? sentryTraceHeaders.join(',')\n : sentryTraceHeaders) ?? undefined;\n let baggage = req.headers.get('baggage');\n\n let ip = parseForwardedFor(\n req.headers.get('lowerdeck-connecting-ip') ??\n req.headers.get('cf-connecting-ip') ??\n req.headers.get('x-forwarded-for') ??\n req.headers.get('x-real-ip')\n );\n\n let headers = new Headers();\n\n if (corsOk) {\n for (let [key, value] of Object.entries(corsHeaders)) {\n headers.append(key, value);\n }\n }\n\n return await Sentry.withIsolationScope(\n async () =>\n await Sentry.continueTrace(\n { sentryTrace, baggage },\n async () =>\n await Sentry.startSpan(\n {\n name: 'rpc request',\n op: 'rpc.server',\n attributes: {\n ip,\n transport: 'http',\n ua: req.headers.get('user-agent') ?? '',\n origin: req.headers.get('origin') ?? ''\n }\n },\n async () => {\n try {\n let beforeSends: Array<() => Promise<any>> = [];\n let id = generateCustomId('req_');\n\n let parseCookies = memo(() =>\n Cookie.parse(req.headers.get('cookie') ?? '')\n );\n\n let request: ServiceRequest = {\n url: req.url,\n headers: req.headers,\n query: url.searchParams,\n body,\n rawBody: body,\n ip,\n requestId: id,\n\n getCookies: () => parseCookies(),\n getCookie: (name: string) => parseCookies()[name],\n setCookie: (name: string, value: string, opts?: any) => {\n let cookie = Cookie.serialize(name, value, opts);\n // @ts-ignore\n headers.append('Set-Cookie', cookie);\n },\n\n beforeSend: (handler: () => Promise<any>) => {\n beforeSends.push(handler);\n },\n\n sharedMiddlewareMemo: new Map<string, Promise<any>>(),\n\n appendHeaders: (newHeaders: Record<string, string | string[]>) => {\n for (let [key, value] of Object.entries(newHeaders)) {\n if (Array.isArray(value)) {\n for (let v of value) headers.append(key, v);\n } else {\n headers.append(key, value);\n }\n }\n }\n };\n\n Sentry.getCurrentScope().setContext('rpc.request', {\n url: req.url,\n query: Object.fromEntries(url.searchParams.entries())\n });\n\n Sentry.getCurrentScope().addAttachment({\n filename: 'rpc.request.body.json',\n data: body,\n contentType: 'application/json'\n });\n\n return provideExecutionContext(\n createExecutionContext({\n type: 'request',\n contextId: id,\n ip: ip ?? '0.0.0.0',\n userAgent: req.headers.get('user-agent') ?? ''\n }),\n async () => {\n let callsByRpc = new Map<\n number,\n { id: string; name: string; payload: any }[]\n >();\n\n let resRef = {\n body: {\n __typename: 'rpc.response',\n calls: [] as any[]\n },\n status: 200\n };\n\n let pathParts = url.pathname.split('/').filter(Boolean);\n let lastPart = pathParts[pathParts.length - 1];\n\n if (lastPart[0] == '$') {\n let id = lastPart.slice(1);\n let rpcIndex = handlerNameToRpcMap.get(id);\n if (rpcIndex == undefined) {\n return new Response(\n JSON.stringify(\n notFoundError({ entity: 'handler' }).toResponse()\n ),\n { status: 404, headers }\n );\n }\n\n let calls = callsByRpc.get(rpcIndex) ?? [];\n calls.push({\n id: generateCustomId('call_'),\n name: id,\n payload: body\n });\n callsByRpc.set(rpcIndex, calls);\n } else {\n let valRes = validation.validate(body);\n if (!valRes.success) {\n return new Response(\n JSON.stringify(\n validationError({\n errors: valRes.errors,\n entity: 'request_data'\n }).toResponse()\n ),\n { status: 406, headers }\n );\n }\n\n for (let call of valRes.value.calls) {\n let rpcIndex = handlerNameToRpcMap.get(call.name);\n if (rpcIndex == undefined) {\n return new Response(\n JSON.stringify(\n notFoundError({ entity: 'handler' }).toResponse()\n ),\n { status: 404, headers }\n );\n }\n\n let calls = callsByRpc.get(rpcIndex) ?? [];\n calls.push(call as any);\n callsByRpc.set(rpcIndex, calls);\n }\n }\n\n await Promise.all(\n Array.from(callsByRpc.entries()).map(async ([rpcIndex, calls]) => {\n let rpc = rpcs[rpcIndex];\n let res = await rpc.runMany(request, {\n requestId: id,\n calls\n });\n\n resRef.status = Math.max(resRef.status, res.status);\n resRef.body.calls.push(...res.body.calls);\n })\n );\n\n headers.append('x-req-id', id);\n headers.append('content-type', 'application/rpc+json');\n headers.append('x-powered-by', 'lowerdeck RPC');\n\n await Promise.all(beforeSends.map(s => s()));\n\n return new Response(serialize.encode(resRef.body), {\n status: resRef.status,\n headers\n });\n }\n );\n } catch (e) {\n console.error(e);\n\n Sentry.captureException(e);\n\n return new Response(JSON.stringify(internalServerError().toResponse()), {\n status: 500,\n headers\n });\n }\n }\n )\n )\n );\n }\n };\n};\n","import { internalServerError, isServiceError, notFoundError } from '@lowerdeck/error';\nimport { getSentry } from '@lowerdeck/sentry';\nimport { Controller, Handler, ServiceRequest } from './controller';\n\nlet Sentry = getSentry();\n\nexport let createServer =\n (opts: {\n onError?: (opts: {\n request: ServiceRequest;\n error: any;\n reqId: string;\n callId: string;\n callName: string;\n }) => void;\n onRequest?: (opts: {\n reqId: string;\n callId: string;\n callName: string;\n request: ServiceRequest;\n response: { status: number; body: any };\n }) => void;\n }) =>\n (controller: Controller<any>) => {\n let findHandler = (name: string): Handler<any, any, any> | null => {\n let parts = name.split(':');\n let current = controller;\n\n while (current && parts.length > 0) {\n current = current[parts.shift()!];\n if (!current) return null;\n }\n\n if (current && current instanceof Handler) return current;\n\n return null;\n };\n\n let getSupportedHandlerNames = (controller: Controller<any>): string[] =>\n Object.entries(controller).flatMap(([key, value]) => {\n if (value instanceof Handler) return [key];\n if (typeof value == 'object')\n return getSupportedHandlerNames(value).map(name => `${key}:${name}`);\n return [];\n });\n\n let handlerNames = getSupportedHandlerNames(controller);\n\n let run = async (\n req: ServiceRequest,\n call: { id: string; name: string; payload: any },\n reqId: string\n ): Promise<{\n response: any;\n status: number;\n request: ServiceRequest;\n }> => {\n let request = { ...req, body: call.payload };\n\n try {\n let handler = findHandler(call.name);\n\n if (!handler) {\n return {\n request,\n status: 404,\n response: notFoundError({ entity: 'handler' }).toResponse()\n };\n }\n\n let response = await handler.run(request, {});\n\n return {\n status: 200,\n request: req,\n response: response.response\n };\n } catch (e) {\n console.error(e);\n\n if (isServiceError(e)) {\n if (e.data.status >= 500) {\n Sentry.captureException(e, {\n tags: { reqId }\n });\n }\n\n return {\n request,\n status: e.data.status,\n response: e.toResponse()\n };\n }\n\n Sentry.captureException(e, {\n tags: { reqId }\n });\n\n opts.onError?.({\n callName: call.name,\n callId: call.id,\n request: req,\n error: e,\n reqId\n });\n\n return {\n request,\n status: 500,\n response: internalServerError().toResponse()\n };\n }\n };\n\n let runMany = async (\n req: ServiceRequest,\n body: {\n calls: {\n id: string;\n name: string;\n payload: any;\n }[];\n requestId: string;\n }\n ): Promise<{\n status: number;\n body: any;\n }> => {\n let callRes = await Promise.all(\n body.calls.map(async (call, i) => {\n let res = await run(req, call as any, body.requestId);\n\n try {\n opts.onRequest?.({\n reqId: body.requestId,\n callId: call.id,\n callName: call.name,\n request: res.request,\n response: { status: res.status, body: res.response }\n });\n } catch (e) {\n Sentry.captureException(e);\n console.error(e);\n }\n\n return {\n __typename: 'rpc.response.call',\n id: call.id,\n name: call.name,\n status: res.status,\n result: res.response\n };\n })\n );\n\n return {\n status: Math.max(...callRes.map(c => c.status)),\n body: {\n __typename: 'rpc.response',\n calls: callRes\n }\n };\n };\n\n return {\n handlerNames,\n runMany\n\n // fetch,\n\n // http: async (\n // req: IncomingMessage & {\n // body: any;\n // },\n // res: ServerResponse & { send: (body: any) => void }\n // ) => {\n // let headers = new Headers(\n // Object.fromEntries(\n // Object.entries(req.headers).map(([key, value]) => [\n // key,\n // value === undefined ? '' : String(value)\n // ])\n // )\n // );\n // let url = new URL(req.url ?? '', `http://${req.headers.host}`);\n\n // let request = new Request(url.toString(), {\n // method: req.method,\n // headers,\n // body: JSON.stringify(req.body)\n // });\n\n // let response = await fetch(request);\n\n // res.statusCode = response.status;\n\n // for (let [key, value] of response.headers.entries()) {\n // res.setHeader(key, value);\n // }\n\n // res.send(response.body);\n // }\n };\n };\n","export let parseForwardedFor = (xForwardedForHeader?: string | null | undefined) => {\n if (typeof xForwardedForHeader != 'string') return undefined;\n\n let ips = xForwardedForHeader\n .split(',')\n .map(ip => ip.trim())\n .filter(Boolean);\n return ips.length > 0 ? ips[0] : undefined;\n};\n"],"names":["_settle","pact","state","value","s","_Pact","o","bind","v","then","observer","prototype","onFulfilled","onRejected","result","this","callback","e","_this","_isSettledPact","thenable","Group","_middleware","_proto","use","handler","opts","concat","ctx","_exit","_temp2","_result","res","key","sharedMiddlewareMemo","set","Promise","resolve","getSharedMemoKey","_temp","has","get","_await$ctx$sharedMidd","reject","createMiddleware","input","_exit2","_temp4","_result2","_temp3","_await$ctx$sharedMidd2","Handler","controller","handlers","_handler","_validation","_proto2","undefined","Error","push","validation","run","req","initialContext","_temp6","_extends","body","response","valRes","validate","success","ServiceError","validationError","errors","entity","_temp5","_forOf","mw","Sentry","getSentry","object","calls","array","id","string","name","payload","any","getSupportedHandlerNames","Object","entries","flatMap","_ref","map","handlerNames","runMany","all","call","i","reqId","request","parts","split","current","length","shift","findHandler","status","notFoundError","toResponse","_catch","console","error","isServiceError","data","captureException","tags","onError","callName","callId","internalServerError","requestId","onRequest","__typename","callRes","Math","max","apply","c","rpcs","handlerNameToRpcMap","Map","rpc","path","fetch","_req$headers$get6","_opts$cors","_ref2","_ref3","_req$headers$get","sentryTraceHeaders","headers","sentryTrace","Array","isArray","join","baggage","ip","xForwardedForHeader","ips","trim","filter","Boolean","parseForwardedFor","Headers","corsOk","_i","_Object$entries","corsHeaders","_Object$entries$_i","append","withIsolationScope","continueTrace","_req$headers$get2","_req$headers$get3","startSpan","op","attributes","transport","ua","origin","_req$headers$get5","beforeSends","generateCustomId","parseCookies","memo","_req$headers$get4","Cookie","parse","url","query","searchParams","rawBody","getCookies","getCookie","setCookie","cookie","serialize","beforeSend","appendHeaders","newHeaders","_i2","_Object$entries2","_Object$entries2$_i","_step","_iterator","_createForOfIteratorHelperLoose","done","getCurrentScope","setContext","fromEntries","addAttachment","filename","contentType","provideExecutionContext","createExecutionContext","type","contextId","userAgent","callsByRpc","resRef","pathParts","pathname","lastPart","_callsByRpc$get","slice","rpcIndex","Response","JSON","stringify","_iterator2","_step2","_callsByRpc$get2","from","_ref4","_resRef$body$calls","encode","cors","rootDomain","URL","hostname","domains","includes","check","additionalCorsHeaders","method","_decode","decode","text","_req$text","_Response","notAcceptableError","message"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/controller.ts","../src/rpcMux.ts","../src/server.ts","../src/extractIp.ts"],"sourcesContent":["import { ServiceError, validationError } from '@lowerdeck/error';\nimport { ValidationType } from '@lowerdeck/validation';\nimport * as Cookie from 'cookie';\n\nexport type Method = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\nexport interface ServiceRequest {\n query: URLSearchParams;\n headers: Headers;\n url: string;\n ip?: string;\n body: any;\n rawBody: any;\n requestId: string;\n\n getCookies: () => Record<string, string | undefined>;\n getCookie: (name: string) => string | undefined;\n setCookie: (name: string, value: string, opts?: Cookie.SerializeOptions) => void;\n\n sharedMiddlewareMemo: Map<string, Promise<any>>;\n beforeSend: (handler: () => Promise<any>) => void;\n appendHeaders: (headers: Record<string, string | string[]>) => void;\n}\n\nexport type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};\nexport type ExtendContext<C extends object, E> = E extends object ? Simplify<C & E> : C;\n\nexport class Group<Context extends { [key: string]: any } = {}> {\n constructor(\n private _middleware: Array<(ctx: Context & ServiceRequest) => Promise<any>> = []\n ) {}\n\n use<T extends { [key: string]: any } | undefined | void>(\n handler: (ctx: Context & ServiceRequest) => Promise<T>,\n opts?: {\n getSharedMemoKey?: (ctx: Context & ServiceRequest) => string;\n }\n ) {\n let middleware = async (ctx: Parameters<typeof handler>[0]): Promise<T> => {\n let key = opts?.getSharedMemoKey?.(ctx);\n if (key && ctx.sharedMiddlewareMemo.has(key)) {\n return await ctx.sharedMiddlewareMemo.get(key)!;\n }\n\n let res = handler(ctx);\n if (key) ctx.sharedMiddlewareMemo.set(key, res);\n\n return await res;\n };\n\n return new Group<Simplify<Context & T>>([...this._middleware, middleware]);\n }\n\n createMiddleware<T extends { [key: string]: any }, P = void>(\n handler: (ctx: Context & ServiceRequest, input: P) => Promise<T>,\n opts?: {\n getSharedMemoKey?: (ctx: Context & ServiceRequest, input: P) => string;\n }\n ) {\n return (input: P) =>\n async (ctx: Context & ServiceRequest): Promise<T> => {\n let key = opts?.getSharedMemoKey?.(ctx, input);\n if (key && ctx.sharedMiddlewareMemo.has(key)) {\n return await ctx.sharedMiddlewareMemo.get(key)!;\n }\n\n let res = handler(ctx, input);\n if (key) ctx.sharedMiddlewareMemo.set(key, res);\n\n return await res;\n };\n }\n\n handler() {\n return new Handler([...this._middleware]);\n }\n\n controller<\n HandlersAndSubControllers extends {\n [key: string]: Handler<any, any, any> | Controller<any>;\n }\n >(handlers: HandlersAndSubControllers): Controller<HandlersAndSubControllers> {\n return handlers;\n }\n}\n\nexport type Controller<\n HandlersAndSubControllers extends { [key: string]: Handler<any, any, any> | Controller<any> }\n> = HandlersAndSubControllers;\n\nexport type InferControllerType<T> = T extends Controller<infer U> ? U : never;\n\nexport type InferClient<\n HandlersAndSubControllers extends { [key: string]: Handler<any, any, any> | Controller<any> }\n> = {\n [K in keyof HandlersAndSubControllers]: HandlersAndSubControllers[K] extends Handler<\n infer I,\n infer O,\n infer C\n >\n ? ((\n input: I,\n opts?: { headers?: Record<string, string>; query?: Record<string, string> }\n ) => Promise<O>) & {\n getFull: (\n input: I,\n opts?: { headers?: Record<string, string>; query?: Record<string, string> }\n ) => Promise<{\n data: O;\n status: number;\n headers: Record<string, string>;\n }>;\n }\n : HandlersAndSubControllers[K] extends Controller<infer U>\n ? InferClient<U>\n : never;\n};\n\nexport class Handler<Input, Output, Context extends { [key: string]: any } = {}> {\n private _handler!: (\n ctx: Context & Omit<ServiceRequest, 'body'> & { input: Input }\n ) => Promise<Output>;\n private _validation: ValidationType<Input> | undefined;\n\n constructor(\n private _middleware: Array<(ctx: Context & ServiceRequest) => Promise<any>> = []\n ) {}\n\n do<HandlerOutput>(\n handler: (\n ctx: Context & Omit<ServiceRequest, 'body'> & { input: Input }\n ) => Promise<HandlerOutput>\n ) {\n if (this._handler != undefined) throw new Error('Handler already defined');\n\n // @ts-ignore\n this._handler = handler;\n\n return this as any as Handler<Input, HandlerOutput, Context>;\n }\n\n use<T extends { [key: string]: any } = {}>(\n handler: (ctx: Context & ServiceRequest) => Promise<T | undefined | void>\n ) {\n this._middleware.push(handler);\n return this as any as Handler<Input, Output, ExtendContext<Context, T>>;\n }\n\n input<HandlerInput>(validation: ValidationType<HandlerInput>) {\n if (this._validation != undefined) throw new Error('Input validation already defined');\n\n // @ts-ignore\n this._validation = validation;\n\n return this as any as Handler<HandlerInput, Output, Context>;\n }\n\n async run(\n req: ServiceRequest,\n initialContext: any\n ): Promise<{\n response: Output;\n }> {\n if (!this._handler) throw new Error('Handler not defined');\n\n let input = req.body as Input;\n\n if (this._validation) {\n let valRes = this._validation.validate(req.body);\n\n if (!valRes.success) {\n throw new ServiceError(\n validationError({ errors: valRes.errors, entity: 'call_data' })\n );\n }\n\n input = valRes.value;\n }\n\n let ctx = {\n ...initialContext,\n ...req,\n\n // Always use the sanitized input\n body: input\n };\n\n for (let mw of this._middleware) {\n let res = await mw(ctx);\n if (res) ctx = { ...ctx, ...res };\n }\n\n let res = await this._handler({\n ...ctx,\n input,\n body: undefined\n });\n\n return {\n response: res\n };\n }\n}\n","import {\n internalServerError,\n notAcceptableError,\n notFoundError,\n validationError\n} from '@lowerdeck/error';\nimport { createExecutionContext, provideExecutionContext } from '@lowerdeck/execution-context';\nimport { generateCustomId } from '@lowerdeck/id';\nimport { memo } from '@lowerdeck/memo';\nimport { getSentry } from '@lowerdeck/sentry';\nimport { serialize } from '@lowerdeck/serialize';\nimport { v } from '@lowerdeck/validation';\nimport * as Cookie from 'cookie';\nimport { ServiceRequest } from './controller';\nimport { parseForwardedFor } from './extractIp';\n\nlet Sentry = getSentry();\n\nlet validation = v.object({\n calls: v.array(\n v.object({\n id: v.string(),\n name: v.string(),\n payload: v.any()\n })\n )\n});\n\nexport let rpcMux = (\n opts: {\n path: string;\n cors?: {\n headers?: string[];\n } & ({ domains: string[] } | { check: (origin: string) => boolean });\n },\n rpcs: {\n handlerNames: string[];\n runMany: (\n req: ServiceRequest,\n body: {\n requestId: string;\n calls: {\n id: string;\n name: string;\n payload: any;\n }[];\n }\n ) => Promise<{\n status: number;\n body: {\n calls: any[];\n };\n }>;\n }[]\n) => {\n let handlerNameToRpcMap = new Map<string, number>(\n rpcs.flatMap((rpc, i) => rpc.handlerNames.map(name => [name, i]))\n );\n\n return {\n path: opts.path,\n\n fetch: async (req: any): Promise<any> => {\n let origin = req.headers.get('origin') ?? '';\n let corsOk = false;\n\n if (opts.cors && 'domains' in opts.cors) {\n try {\n let url = new URL(origin);\n let rootDomain = url.hostname.split('.').slice(-2).join('.');\n corsOk = opts.cors.domains.includes(rootDomain);\n } catch (e) {\n // Ignore -> no cors\n }\n } else if (opts.cors && 'check' in opts.cors) {\n corsOk = opts.cors.check(origin);\n }\n\n let url = new URL(req.url);\n\n let additionalCorsHeaders = opts.cors?.headers?.join(', ');\n if (additionalCorsHeaders) additionalCorsHeaders = `, ${additionalCorsHeaders}`.trim();\n\n let corsHeaders: Record<string, string> = corsOk\n ? {\n 'access-control-allow-origin': origin,\n 'access-control-allow-methods': 'POST, OPTIONS',\n 'access-control-allow-headers': `Content-Type, Authorization, Baggage, Sentry-Trace${\n additionalCorsHeaders ?? ''\n }`,\n 'access-control-max-age': '604800',\n 'access-control-allow-credentials': 'true'\n }\n : {};\n\n if (req.method == 'OPTIONS') {\n if (corsOk) {\n return new Response(null, {\n status: 204,\n headers: corsHeaders\n });\n }\n\n return new Response(null, { status: 403 });\n }\n\n let body: any = null;\n\n try {\n body = serialize.decode(await req.text());\n } catch (e) {\n return new Response(\n JSON.stringify(notAcceptableError({ message: 'Invalid JSON' }).toResponse()),\n { status: 406 }\n );\n }\n\n let sentryTraceHeaders = req.headers.get('sentry-trace');\n let sentryTrace =\n (Array.isArray(sentryTraceHeaders)\n ? sentryTraceHeaders.join(',')\n : sentryTraceHeaders) ?? undefined;\n let baggage = req.headers.get('baggage');\n\n let ip = parseForwardedFor(\n req.headers.get('lowerdeck-connecting-ip') ??\n req.headers.get('cf-connecting-ip') ??\n req.headers.get('x-forwarded-for') ??\n req.headers.get('x-real-ip')\n );\n\n let headers = new Headers();\n\n if (corsOk) {\n for (let [key, value] of Object.entries(corsHeaders)) {\n headers.append(key, value);\n }\n }\n\n return await Sentry.withIsolationScope(\n async () =>\n await Sentry.continueTrace(\n { sentryTrace, baggage },\n async () =>\n await Sentry.startSpan(\n {\n name: 'rpc request',\n op: 'rpc.server',\n attributes: {\n ip,\n transport: 'http',\n ua: req.headers.get('user-agent') ?? '',\n origin: req.headers.get('origin') ?? ''\n }\n },\n async () => {\n try {\n let beforeSends: Array<() => Promise<any>> = [];\n let id = generateCustomId('req_');\n\n let parseCookies = memo(() =>\n Cookie.parse(req.headers.get('cookie') ?? '')\n );\n\n let request: ServiceRequest = {\n url: req.url,\n headers: req.headers,\n query: url.searchParams,\n body,\n rawBody: body,\n ip,\n requestId: id,\n\n getCookies: () => parseCookies(),\n getCookie: (name: string) => parseCookies()[name],\n setCookie: (name: string, value: string, opts?: any) => {\n let cookie = Cookie.serialize(name, value, opts);\n // @ts-ignore\n headers.append('Set-Cookie', cookie);\n },\n\n beforeSend: (handler: () => Promise<any>) => {\n beforeSends.push(handler);\n },\n\n sharedMiddlewareMemo: new Map<string, Promise<any>>(),\n\n appendHeaders: (newHeaders: Record<string, string | string[]>) => {\n for (let [key, value] of Object.entries(newHeaders)) {\n if (Array.isArray(value)) {\n for (let v of value) headers.append(key, v);\n } else {\n headers.append(key, value);\n }\n }\n }\n };\n\n Sentry.getCurrentScope().setContext('rpc.request', {\n url: req.url,\n query: Object.fromEntries(url.searchParams.entries())\n });\n\n Sentry.getCurrentScope().addAttachment({\n filename: 'rpc.request.body.json',\n data: body,\n contentType: 'application/json'\n });\n\n return provideExecutionContext(\n createExecutionContext({\n type: 'request',\n contextId: id,\n ip: ip ?? '0.0.0.0',\n userAgent: req.headers.get('user-agent') ?? ''\n }),\n async () => {\n let callsByRpc = new Map<\n number,\n { id: string; name: string; payload: any }[]\n >();\n\n let resRef = {\n body: {\n __typename: 'rpc.response',\n calls: [] as any[]\n },\n status: 200\n };\n\n let pathParts = url.pathname.split('/').filter(Boolean);\n let lastPart = pathParts[pathParts.length - 1];\n\n let isSingle = lastPart[0] == '$';\n\n if (isSingle) {\n let id = lastPart.slice(1);\n let rpcIndex = handlerNameToRpcMap.get(id);\n if (rpcIndex == undefined) {\n return new Response(\n JSON.stringify(\n notFoundError({ entity: 'handler' }).toResponse()\n ),\n { status: 404, headers }\n );\n }\n\n let calls = callsByRpc.get(rpcIndex) ?? [];\n calls.push({\n id: generateCustomId('call_'),\n name: id,\n payload: body\n });\n callsByRpc.set(rpcIndex, calls);\n } else {\n let valRes = validation.validate(body);\n if (!valRes.success) {\n return new Response(\n JSON.stringify(\n validationError({\n errors: valRes.errors,\n entity: 'request_data'\n }).toResponse()\n ),\n { status: 406, headers }\n );\n }\n\n for (let call of valRes.value.calls) {\n let rpcIndex = handlerNameToRpcMap.get(call.name);\n if (rpcIndex == undefined) {\n return new Response(\n JSON.stringify(\n notFoundError({ entity: 'handler' }).toResponse()\n ),\n { status: 404, headers }\n );\n }\n\n let calls = callsByRpc.get(rpcIndex) ?? [];\n calls.push(call as any);\n callsByRpc.set(rpcIndex, calls);\n }\n }\n\n await Promise.all(\n Array.from(callsByRpc.entries()).map(async ([rpcIndex, calls]) => {\n let rpc = rpcs[rpcIndex];\n let res = await rpc.runMany(request, {\n requestId: id,\n calls\n });\n\n resRef.status = Math.max(resRef.status, res.status);\n resRef.body.calls.push(...res.body.calls);\n })\n );\n\n headers.append('x-req-id', id);\n headers.append('content-type', 'application/rpc+json');\n headers.append('x-powered-by', 'lowerdeck RPC');\n\n await Promise.all(beforeSends.map(s => s()));\n\n return new Response(\n serialize.encode(\n isSingle ? resRef.body.calls[0].result : resRef.body\n ),\n {\n status: resRef.status,\n headers\n }\n );\n }\n );\n } catch (e) {\n console.error(e);\n\n Sentry.captureException(e);\n\n return new Response(JSON.stringify(internalServerError().toResponse()), {\n status: 500,\n headers\n });\n }\n }\n )\n )\n );\n }\n };\n};\n","import { internalServerError, isServiceError, notFoundError } from '@lowerdeck/error';\nimport { getSentry } from '@lowerdeck/sentry';\nimport { Controller, Handler, ServiceRequest } from './controller';\n\nlet Sentry = getSentry();\n\nexport let createServer =\n (opts: {\n onError?: (opts: {\n request: ServiceRequest;\n error: any;\n reqId: string;\n callId: string;\n callName: string;\n }) => void;\n onRequest?: (opts: {\n reqId: string;\n callId: string;\n callName: string;\n request: ServiceRequest;\n response: { status: number; body: any };\n }) => void;\n }) =>\n (controller: Controller<any>) => {\n let findHandler = (name: string): Handler<any, any, any> | null => {\n let parts = name.split(':');\n let current = controller;\n\n while (current && parts.length > 0) {\n current = current[parts.shift()!];\n if (!current) return null;\n }\n\n if (current && current instanceof Handler) return current;\n\n return null;\n };\n\n let getSupportedHandlerNames = (controller: Controller<any>): string[] =>\n Object.entries(controller).flatMap(([key, value]) => {\n if (value instanceof Handler) return [key];\n if (typeof value == 'object')\n return getSupportedHandlerNames(value).map(name => `${key}:${name}`);\n return [];\n });\n\n let handlerNames = getSupportedHandlerNames(controller);\n\n let run = async (\n req: ServiceRequest,\n call: { id: string; name: string; payload: any },\n reqId: string\n ): Promise<{\n response: any;\n status: number;\n request: ServiceRequest;\n }> => {\n let request = { ...req, body: call.payload };\n\n try {\n let handler = findHandler(call.name);\n\n if (!handler) {\n return {\n request,\n status: 404,\n response: notFoundError({ entity: 'handler' }).toResponse()\n };\n }\n\n let response = await handler.run(request, {});\n\n return {\n status: 200,\n request: req,\n response: response.response\n };\n } catch (e) {\n console.error(e);\n\n if (isServiceError(e)) {\n if (e.data.status >= 500) {\n Sentry.captureException(e, {\n tags: { reqId }\n });\n }\n\n return {\n request,\n status: e.data.status,\n response: e.toResponse()\n };\n }\n\n Sentry.captureException(e, {\n tags: { reqId }\n });\n\n opts.onError?.({\n callName: call.name,\n callId: call.id,\n request: req,\n error: e,\n reqId\n });\n\n return {\n request,\n status: 500,\n response: internalServerError().toResponse()\n };\n }\n };\n\n let runMany = async (\n req: ServiceRequest,\n body: {\n calls: {\n id: string;\n name: string;\n payload: any;\n }[];\n requestId: string;\n }\n ): Promise<{\n status: number;\n body: any;\n }> => {\n let callRes = await Promise.all(\n body.calls.map(async (call, i) => {\n let res = await run(req, call as any, body.requestId);\n\n try {\n opts.onRequest?.({\n reqId: body.requestId,\n callId: call.id,\n callName: call.name,\n request: res.request,\n response: { status: res.status, body: res.response }\n });\n } catch (e) {\n Sentry.captureException(e);\n console.error(e);\n }\n\n return {\n __typename: 'rpc.response.call',\n id: call.id,\n name: call.name,\n status: res.status,\n result: res.response\n };\n })\n );\n\n return {\n status: Math.max(...callRes.map(c => c.status)),\n body: {\n __typename: 'rpc.response',\n calls: callRes\n }\n };\n };\n\n return {\n handlerNames,\n runMany\n\n // fetch,\n\n // http: async (\n // req: IncomingMessage & {\n // body: any;\n // },\n // res: ServerResponse & { send: (body: any) => void }\n // ) => {\n // let headers = new Headers(\n // Object.fromEntries(\n // Object.entries(req.headers).map(([key, value]) => [\n // key,\n // value === undefined ? '' : String(value)\n // ])\n // )\n // );\n // let url = new URL(req.url ?? '', `http://${req.headers.host}`);\n\n // let request = new Request(url.toString(), {\n // method: req.method,\n // headers,\n // body: JSON.stringify(req.body)\n // });\n\n // let response = await fetch(request);\n\n // res.statusCode = response.status;\n\n // for (let [key, value] of response.headers.entries()) {\n // res.setHeader(key, value);\n // }\n\n // res.send(response.body);\n // }\n };\n };\n","export let parseForwardedFor = (xForwardedForHeader?: string | null | undefined) => {\n if (typeof xForwardedForHeader != 'string') return undefined;\n\n let ips = xForwardedForHeader\n .split(',')\n .map(ip => ip.trim())\n .filter(Boolean);\n return ips.length > 0 ? ips[0] : undefined;\n};\n"],"names":["_settle","pact","state","value","s","_Pact","o","bind","v","then","observer","prototype","onFulfilled","onRejected","result","this","callback","e","_this","_isSettledPact","thenable","Group","_middleware","_proto","use","handler","opts","concat","ctx","_exit","_temp2","_result","res","key","sharedMiddlewareMemo","set","Promise","resolve","getSharedMemoKey","_temp","has","get","_await$ctx$sharedMidd","reject","createMiddleware","input","_exit2","_temp4","_result2","_temp3","_await$ctx$sharedMidd2","Handler","controller","handlers","_handler","_validation","_proto2","undefined","Error","push","validation","run","req","initialContext","_temp6","_extends","body","response","valRes","validate","success","ServiceError","validationError","errors","entity","_temp5","_forOf","mw","Sentry","getSentry","object","calls","array","id","string","name","payload","any","getSupportedHandlerNames","Object","entries","flatMap","_ref","map","handlerNames","runMany","all","call","i","reqId","request","parts","split","current","length","shift","findHandler","status","notFoundError","toResponse","_catch","console","error","isServiceError","data","captureException","tags","onError","callName","callId","internalServerError","requestId","onRequest","__typename","callRes","Math","max","apply","c","rpcs","handlerNameToRpcMap","Map","rpc","path","fetch","_req$headers$get6","_opts$cors","_ref2","_ref3","_req$headers$get","sentryTraceHeaders","headers","sentryTrace","Array","isArray","join","baggage","ip","xForwardedForHeader","ips","trim","filter","Boolean","parseForwardedFor","Headers","corsOk","_i","_Object$entries","corsHeaders","_Object$entries$_i","append","withIsolationScope","continueTrace","_req$headers$get2","_req$headers$get3","startSpan","op","attributes","transport","ua","origin","_req$headers$get5","beforeSends","generateCustomId","parseCookies","memo","_req$headers$get4","Cookie","parse","url","query","searchParams","rawBody","getCookies","getCookie","setCookie","cookie","serialize","beforeSend","appendHeaders","newHeaders","_i2","_Object$entries2","_Object$entries2$_i","_iterator","_step","_createForOfIteratorHelperLoose","done","getCurrentScope","setContext","fromEntries","addAttachment","filename","contentType","provideExecutionContext","createExecutionContext","type","contextId","userAgent","callsByRpc","resRef","pathParts","pathname","lastPart","isSingle","_callsByRpc$get","slice","rpcIndex","Response","JSON","stringify","_iterator2","_step2","_callsByRpc$get2","from","_ref4","_resRef$body$calls","encode","cors","rootDomain","URL","hostname","domains","includes","check","additionalCorsHeaders","method","_decode","decode","text","_req$text","_Response","notAcceptableError","message"],"mappings":"8lEA6HY,SAAAA,EAAAC,EAAAC,EAAAC,GANF,IAAAF,EAAAG,EAEa,CACb,GAAAD,aAAAE,EAA+C,CAEvD,IAAAF,EAAAC,EAYE,cADaE,EAAAN,EAAAO,KAAA,KAAAN,EAAAC,IAVM,EAAXA,IACNA,EAAAC,EAAAC,GAOFD,EAAIA,EAAaK,EAQnB,GAAAL,GAC2EA,EAAAM,KAGzE,YADAN,EAAAM,KAAgBT,EAAAO,UAAMN,EAASC,GAAAF,EAAAO,KAAA,KAAAN,EAAA,IAIjCA,EAAAG,EAA4DF,EAC1DD,EAAAO,EAAAL,EAAmC,IAAAO,EAAUT,EAAAK,KAG7CI,EAAIT,GAKN,KAlIWI,eAAK,WAEN,SAAAA,IAAA,CAqDR,OAtDFA,EAAAM,wBACkFC,EAAAC,OAAxEC,EAAW,IAAAT,EACjBH,EAAAa,KAAAX,KAEDF,EACqD,CAKtD,IAAAc,EAAiB,IAAOJ,EAAkDC,OACpE,SAEK,EAAAG,EAAUD,KAAAP,UAClBS,GAEDjB,EAAAc,EAAU,EAAAG,EACV,UAGF,OAAEF,iBAKYT,EAAA,SAAAY,aAQNA,EAAMV,EACN,IAAAJ,MACK,EAAAQ,EAAUA,EAAAT,GAA4BA,GAC9CU,IAEGC,IAAaD,EAAMV,YAIzB,CAAA,MAAEc,GACNjB,EAACc,EAAA,EAAAG,KAIAH,CAED,EAKET,EAvDc,GAwIM,SAAAc,EAAgBC,GAEpC,OAAAA,aAASf,GAAqB,EAAAe,EAAAhB,CAE9B,CA5IS,IAAAiB,0BACX,SAAAA,EACUC,QAAAA,IAAAA,IAAAA,EAAsE,IAAEP,KAAxEO,iBAAA,EAAAP,KAAWO,YAAXA,CACP,CAAC,IAAAC,EAAAF,EAAAV,UAqDHU,OArDGE,EAEJC,IAAA,SACEC,EACAC,GAgBA,WAAWL,KAAKM,OAA4BZ,KAAKO,aAZnC,SAAUM,GAAkD,IAAA,IASxDC,EATwDC,EAAAA,SAAAC,GAAAF,GAAAA,SAAAE,EAMxE,IAAIC,EAAMP,EAAQG,GAC8B,OAA5CK,GAAKL,EAAIM,qBAAqBC,IAAIF,EAAKD,GAAKI,QAAAC,QAEnCL,EAAGH,EARZI,EAAU,MAAJP,SAAAA,EAAMY,wBAANZ,EAAMY,iBAAmBV,GAAKW,EACpCN,WAAAA,GAAAA,GAAOL,EAAIM,qBAAqBM,IAAIP,GAAI,OAAAG,QAAAC,QAC7BT,EAAIM,qBAAqBO,IAAIR,IAAKxB,KAAA,SAAAiC,UAAAb,IAAAa,CAAA,EAAA,CAD7CT,GAC6C,OAAAG,QAAAC,QAAAE,GAAAA,EAAA9B,KAAA8B,EAAA9B,KAAAqB,GAAAA,EAAAS,GAOnD,CAAC,MAAAtB,GAAA,OAAAmB,QAAAO,OAAA1B,EAED,CAAA,IACF,EAACM,EAEDqB,iBAAA,SACEnB,EACAC,GAIA,gBAAQmB,GAAQ,OAAA,SACPjB,GAA6C,IAAA,IASlCkB,EATkCC,EAAAA,SAAAC,GAAAF,GAAAA,SAAAE,EAMlD,IAAIhB,EAAMP,EAAQG,EAAKiB,GACyB,OAA5CZ,GAAKL,EAAIM,qBAAqBC,IAAIF,EAAKD,GAAKI,QAAAC,QAEnCL,EAAG,EARZC,EAAMP,MAAAA,GAAsB,MAAtBA,EAAMY,sBAAgB,EAAtBZ,EAAMY,iBAAmBV,EAAKiB,GAAOI,EAC3ChB,WAAAA,GAAAA,GAAOL,EAAIM,qBAAqBM,IAAIP,UAAIG,QAAAC,QAC7BT,EAAIM,qBAAqBO,IAAIR,IAAKxB,KAAA,SAAAyC,UAAAJ,IAAAI,CAAA,EAAA,CAD7CjB,GAC6C,OAAAG,QAAAC,QAAAY,GAAAA,EAAAxC,KAAAwC,EAAAxC,KAAAsC,GAAAA,EAAAE,GAOnD,CAAC,MAAAhC,GAAAmB,OAAAA,QAAAO,OAAA1B,EACL,CAAA,CAAA,CAAA,EAACM,EAEDE,QAAA,WACE,OAAO,IAAI0B,EAAO,GAAAxB,OAAKZ,KAAKO,aAC9B,EAACC,EAED6B,WAAA,SAIEC,GACA,OAAOA,CACT,EAAChC,CAAA,IAmCU8B,eAMX,WAAA,SAAAA,EACU7B,YAAAA,IAAAA,EAAsE,IAAtEA,KAAAA,iBANFgC,EAAAA,KAAAA,qBAGAC,iBAAW,EAGTxC,KAAWO,YAAXA,CACP,CAAC,IAAAkC,EAAAL,EAAAxC,UA2EH,OA3EG6C,EAAA,GAEJ,SACE/B,GAIA,GAAqBgC,MAAjB1C,KAAKuC,SAAuB,MAAU,IAAAI,MAAM,2BAKhD,OAFA3C,KAAKuC,SAAW7B,MAGlB,EAAC+B,EAEDhC,IAAA,SACEC,GAGA,OADAV,KAAKO,YAAYqC,KAAKlC,GACfV,IACT,EAACyC,EAEDX,MAAA,SAAoBe,GAClB,GAAwBH,MAApB1C,KAAKwC,YAA0B,MAAU,IAAAG,MAAM,oCAKnD,OAFA3C,KAAKwC,YAAcK,EAEZ7C,IACT,EAACyC,EAEKK,IAAG,SACPC,EACAC,OAAmBC,IAAAA,EAAAA,WAAA5B,OAAAA,QAAAC,QAiCHnB,EAAKoC,SAAQW,EAAA,CAAA,EACxBrC,EACHiB,CAAAA,MAAAA,EACAqB,UAAMT,MACNhD,KAJEuB,SAAAA,GAMJ,MAAO,CACLmC,SAAUnC,EACV,EAAAd,EAAAA,EArCGH,KAAL,IAAKG,EAAKoC,SAAU,MAAU,IAAAI,MAAM,uBAEpC,IAAIb,EAAQiB,EAAII,KAEhB,GAAIhD,EAAKqC,YAAa,CACpB,IAAIa,EAASlD,EAAKqC,YAAYc,SAASP,EAAII,MAE3C,IAAKE,EAAOE,QACV,MAAU,IAAAC,EAAAA,aACRC,EAAeA,gBAAC,CAAEC,OAAQL,EAAOK,OAAQC,OAAQ,eAIrD7B,EAAQuB,EAAOjE,KACjB,CAEA,IAAIyB,EAAGqC,EACFF,CAAAA,EAAAA,EACAD,EAGHI,CAAAA,KAAMrB,IACN8B,6uBAAAC,CAEa1D,EAAKI,qBAAXuD,UAAwBzC,QAAAC,QACfwC,EAAGjD,IAAInB,KAAnBuB,SAAAA,GACAA,IAAKJ,EAAGqC,EAAQrC,CAAAA,EAAAA,EAAQI,GAAM,EACpC,GAAC,OAAAI,QAAAC,QAAAsC,GAAAA,EAAAlE,KAAAkE,EAAAlE,KAAAuD,GAAAA,IAWH,CAAC,MAAA/C,GAAAmB,OAAAA,QAAAO,OAAA1B,EAAA,CAAA,EAAAkC,CAAA,CA7ED,GC5GE2B,EAASC,EAAAA,YAETnB,EAAapD,EAAAA,EAAEwE,OAAO,CACxBC,MAAOzE,EAAAA,EAAE0E,MACP1E,EAAAA,EAAEwE,OAAO,CACPG,GAAI3E,EAACA,EAAC4E,SACNC,KAAM7E,EAAAA,EAAE4E,SACRE,QAAS9E,EAACA,EAAC+E,WCnBbT,EAASC,mDAGX,SAACrD,GAeA,OACA0B,SAAAA,GACC,IAcIoC,EAA2B,SAACpC,GAC9B,OAAAqC,OAAOC,QAAQtC,GAAYuC,QAAQ,SAAAC,GAAE,IAAA3D,EAAG2D,KAAEzF,EAAKyF,EAC7C,GAAA,OAAIzF,aAAiBgD,EAAgB,CAAClB,GAClB,iBAAT9B,EACFqF,EAAyBrF,GAAO0F,IAAI,SAAAR,GAAI,OAAOpD,MAAOoD,CAAI,GAC5D,EACT,EAAE,EAwHJ,MAAO,CACLS,aAvHiBN,EAAyBpC,GAwH1C2C,iBAnDAjC,EACAI,GAWG,IAAA,OAAA9B,QAAAC,QACiBD,QAAQ4D,IAC1B9B,EAAKe,MAAMY,IAAWI,SAAAA,EAAMC,GAAC,WAAI9D,QAAAC,QAjFjC,SACFyB,EACAmC,EACAE,GAKG,IACH,IAAIC,EAAOnC,EAAA,CAAA,EAAQH,EAAKI,CAAAA,KAAM+B,EAAKX,UAAU,OAAAlD,QAAAC,iCAGvCZ,EApCU,SAAC4D,GAIjB,IAHA,IAAIgB,EAAQhB,EAAKiB,MAAM,KACnBC,EAAUnD,EAEPmD,GAAWF,EAAMG,OAAS,GAE/B,KADAD,EAAUA,EAAQF,EAAMI,UACV,OAChB,KAEA,OAAIF,GAAWA,aAAmBpD,EAAgBoD,EAGpD,IAAA,CAwBkBG,CAAYT,EAAKZ,OAEnBjD,QAAAC,QAQSZ,EAAQoC,IAAIuC,EAAS,KAAG3F,cAAzC0D,GAEJ,MAAO,CACLwC,OAAQ,IACRP,QAAStC,EACTK,SAAUA,EAASA,SACnB,GAbO,CACLiC,QAAAA,EACAO,OAAQ,IACRxC,SAAUyC,EAAaA,cAAC,CAAElC,OAAQ,YAAamC,mCAPjD,IACEpF,sCAHuCqF,CAEzC,EAkBK7F,SAAAA,GAGP,OAFA8F,QAAQC,MAAM/F,GAEVgG,iBAAehG,IACbA,EAAEiG,KAAKP,QAAU,KACnB7B,EAAOqC,iBAAiBlG,EAAG,CACzBmG,KAAM,CAAEjB,MAAAA,KAIL,CACLC,QAAAA,EACAO,OAAQ1F,EAAEiG,KAAKP,OACfxC,SAAUlD,EAAE4F,gBAIhB/B,EAAOqC,iBAAiBlG,EAAG,CACzBmG,KAAM,CAAEjB,MAAAA,KAGE,MAAZzE,EAAK2F,SAAL3F,EAAK2F,QAAU,CACbC,SAAUrB,EAAKZ,KACfkC,OAAQtB,EAAKd,GACbiB,QAAStC,EACTkD,MAAO/F,EACPkF,MAAAA,IAGK,CACLC,QAAAA,EACAO,OAAQ,IACRxC,SAAUqD,EAAmBA,sBAAGX,cAEpC,GACF,CAAC,MAAA5F,GAAAmB,OAAAA,QAAAO,OAAA1B,EAAA,CAAA,CAkBqB4C,CAAIC,EAAKmC,EAAa/B,EAAKuD,YAAUhH,cAAjDuB,GAEJ,IACgB,MAAdN,EAAKgG,WAALhG,EAAKgG,UAAY,CACfvB,MAAOjC,EAAKuD,UACZF,OAAQtB,EAAKd,GACbmC,SAAUrB,EAAKZ,KACfe,QAASpE,EAAIoE,QACbjC,SAAU,CAAEwC,OAAQ3E,EAAI2E,OAAQzC,KAAMlC,EAAImC,WAE9C,CAAE,MAAOlD,GACP6D,EAAOqC,iBAAiBlG,GACxB8F,QAAQC,MAAM/F,EAChB,CAEA,MAAO,CACL0G,WAAY,oBACZxC,GAAIc,EAAKd,GACTE,KAAMY,EAAKZ,KACXsB,OAAQ3E,EAAI2E,OACZ7F,OAAQkB,EAAImC,SACZ,EACJ,CAAC,MAAAlD,UAAAmB,QAAAO,OAAA1B,QACFR,KAzBGmH,SAAAA,GA2BJ,MAAO,CACLjB,OAAQkB,KAAKC,IAAGC,MAARF,KAAYD,EAAQ/B,IAAI,SAAAmC,GAAC,OAAIA,EAAErB,MAAM,IAC7CzC,KAAM,CACJyD,WAAY,eACZ1C,MAAO2C,GAET,EACJ,CAAC,MAAA3G,GAAA,OAAAmB,QAAAO,OAAA1B,EAAA,CAAA,EAyCH,CAAC,WD/KiB,SAClBS,EAMAuG,GAoBA,IAAIC,EAAsB,IAAIC,IAC5BF,EAAKtC,QAAQ,SAACyC,EAAKlC,GAAC,OAAKkC,EAAItC,aAAaD,IAAI,SAAAR,GAAQ,MAAA,CAACA,EAAMa,EAAE,EAAC,IAGlE,MAAO,CACLmC,KAAM3G,EAAK2G,KAEXC,MAAKA,SAASxE,GAAQ,IAAkByE,IAAAA,EAAAC,EA0QrC3G,EA1QqCC,EAAAA,SAAAC,GAAA,IAAA6D,EAAA6C,EAAAC,EAAAC,EAAA9G,GAAAA,EAAAE,OAAAA,EAuDtC,IAAI6G,EAAqB9E,EAAI+E,QAAQpG,IAAI,gBACrCqG,EAGoB,OAHTlD,EACZmD,MAAMC,QAAQJ,GACXA,EAAmBK,KAAK,KACxBL,GAAkBhD,OAAKnC,EACzByF,EAAUpF,EAAI+E,QAAQpG,IAAI,WAE1B0G,EE5HqB,SAACC,GAC9B,GAAkC,iBAAvBA,EAAX,CAEA,IAAIC,EAAMD,EACP9C,MAAM,KACNT,IAAI,SAAAsD,GAAE,OAAIA,EAAGG,MAAM,GACnBC,OAAOC,SACV,OAAOH,EAAI7C,OAAS,EAAI6C,EAAI,QAAK5F,CAN2B,CAO9D,CFoHegG,CAG6BhB,OAHZA,SAAAC,EACkB,OADlBC,EACxB7E,EAAI+E,QAAQpG,IAAI,4BAA0BkG,EACxC7E,EAAI+E,QAAQpG,IAAI,qBAAmBiG,EACnC5E,EAAI+E,QAAQpG,IAAI,oBAAkBgG,EAClC3E,EAAI+E,QAAQpG,IAAI,cAGhBoG,EAAU,IAAIa,QAElB,GAAIC,EACF,IAAAC,IAAAA,EAAAC,EAAAA,EAAyBpE,OAAOC,QAAQoE,GAAYF,EAAAC,EAAArD,OAAAoD,IAAE,CAAjD,IAAAG,EAAAF,EAAAD,GACHf,EAAQmB,OADGD,EAAA,GAAOA,EAAA,GAEpB,CACD,OAAA3H,QAAAC,QAEYyC,EAAOmF,mBAAkB7H,WAAAA,IAAAA,OAAAA,QAAAC,QAE5ByC,EAAOoF,cACX,CAAEpB,YAAAA,EAAaI,QAAAA,GAAS,WAAA,IAAA,IAAAiB,EAAAC,EAAA,OAAAhI,QAAAC,QAEhByC,EAAOuF,UACX,CACEhF,KAAM,cACNiF,GAAI,aACJC,WAAY,CACVpB,GAAAA,EACAqB,UAAW,OACXC,GAAiC,OAA/BN,EAAErG,EAAI+E,QAAQpG,IAAI,eAAa0H,EAAI,GACrCO,OAAiCN,OAA3BA,EAAEtG,EAAI+E,QAAQpG,IAAI,WAAS2H,EAAI,KAG9B,WAAA,IACT,IAAI,IAAAO,EACEC,EAAyC,GACzCzF,EAAK0F,EAAAA,iBAAiB,QAEtBC,EAAeC,EAAAA,KAAK,WAAAC,IAAAA,EACtB,OAAAC,EAAOC,MAA+B,OAA1BF,EAAClH,EAAI+E,QAAQpG,IAAI,WAASuI,EAAI,GAAG,GAG3C5E,EAA0B,CAC5B+E,IAAKrH,EAAIqH,IACTtC,QAAS/E,EAAI+E,QACbuC,MAAOD,EAAIE,aACXnH,KAAAA,EACAoH,QAASpH,EACTiF,GAAAA,EACA1B,UAAWtC,EAEXoG,WAAY,WAAF,OAAQT,GAAc,EAChCU,UAAW,SAACnG,GAAY,OAAKyF,IAAezF,EAAK,EACjDoG,UAAW,SAACpG,EAAclF,EAAeuB,GACvC,IAAIgK,EAAST,EAAOU,UAAUtG,EAAMlF,EAAOuB,GAE3CmH,EAAQmB,OAAO,aAAc0B,EAC/B,EAEAE,WAAY,SAACnK,GACXmJ,EAAYjH,KAAKlC,EACnB,EAEAS,qBAAsB,IAAIiG,IAE1B0D,cAAe,SAACC,GACd,IAAA,IAAAC,EAAA,EAAAC,EAAyBvG,OAAOC,QAAQoG,GAAWC,EAAAC,EAAAxF,OAAAuF,IAAE,CAAhD,IAAAE,EAAAD,EAAAD,GAAK9J,EAAGgK,EAAA,GAAE9L,EAAK8L,EAClB,GAAA,GAAIlD,MAAMC,QAAQ7I,GAChB,IAAA+L,IAAmBC,EAAnBD,EAAAE,EAAcjM,KAAKgM,EAAAD,KAAAG,MAAExD,EAAQmB,OAAO/H,EAA1BkK,EAAAhM,YAEV0I,EAAQmB,OAAO/H,EAAK9B,EAExB,CACF,GAcF,OAXA2E,EAAOwH,kBAAkBC,WAAW,cAAe,CACjDpB,IAAKrH,EAAIqH,IACTC,MAAO3F,OAAO+G,YAAYrB,EAAIE,aAAa3F,aAG7CZ,EAAOwH,kBAAkBG,cAAc,CACrCC,SAAU,wBACVxF,KAAMhD,EACNyI,YAAa,qBAGfvK,QAAAC,QAAOuK,EAAAA,wBACLC,EAAAA,uBAAuB,CACrBC,KAAM,UACNC,UAAW5H,EACXgE,SAAIA,EAAAA,EAAM,UACV6D,UAAwC,OAA/BrC,EAAE7G,EAAI+E,QAAQpG,IAAI,eAAakI,EAAI,KAC5C,WAAA,IAEA,IAAIsC,EAAa,IAAI9E,IAKjB+E,EAAS,CACXhJ,KAAM,CACJyD,WAAY,eACZ1C,MAAO,IAET0B,OAAQ,KAGNwG,EAAYhC,EAAIiC,SAAS9G,MAAM,KAAKiD,OAAOC,SAC3C6D,EAAWF,EAAUA,EAAU3G,OAAS,GAExC8G,EAA0B,KAAfD,EAAS,GAExB,GAAIC,EAAU,CAAAC,IAAAA,EACRpI,EAAKkI,EAASG,MAAM,GACpBC,EAAWvF,EAAoBzF,IAAI0C,GACvC,GAAgB1B,MAAZgK,EACF,OAAArL,QAAAC,QAAO,IAAIqL,SACTC,KAAKC,UACHhH,EAAaA,cAAC,CAAElC,OAAQ,YAAamC,cAEvC,CAAEF,OAAQ,IAAKkC,QAAAA,KAInB,IAAI5D,EAAgCsI,OAA3BA,EAAGN,EAAWxK,IAAIgL,IAASF,EAAI,GACxCtI,EAAMtB,KAAK,CACTwB,GAAI0F,EAAgBA,iBAAC,SACrBxF,KAAMF,EACNG,QAASpB,IAEX+I,EAAW9K,IAAIsL,EAAUxI,EAC3B,KAAO,CACL,IAAIb,EAASR,EAAWS,SAASH,GACjC,IAAKE,EAAOE,QACV,OAAAlC,QAAAC,QAAO,IAAIqL,SACTC,KAAKC,UACHpJ,EAAeA,gBAAC,CACdC,OAAQL,EAAOK,OACfC,OAAQ,iBACPmC,cAEL,CAAEF,OAAQ,IAAKkC,QAAAA,KAInB,IAAAgF,IAAmCC,EAAnCD,EAAAzB,EAAiBhI,EAAOjE,MAAM8E,SAAK6I,EAAAD,KAAAxB,MAAE,CAAA0B,IAAAA,EAA5B9H,EAAI6H,EAAA3N,MACPsN,EAAWvF,EAAoBzF,IAAIwD,EAAKZ,MAC5C,GAAgB5B,MAAZgK,EACF,OAAArL,QAAAC,QAAO,IAAIqL,SACTC,KAAKC,UACHhH,EAAaA,cAAC,CAAElC,OAAQ,YAAamC,cAEvC,CAAEF,OAAQ,IAAKkC,QAAAA,KAInB,IAAI5D,SAAK8I,EAAGd,EAAWxK,IAAIgL,IAASM,EAAI,GACxC9I,EAAMtB,KAAKsC,GACXgH,EAAW9K,IAAIsL,EAAUxI,EAC3B,CACF,CAAC,OAAA7C,QAAAC,QAEKD,QAAQ4D,IACZ+C,MAAMiF,KAAKf,EAAWvH,WAAWG,IAAG,SAAAoI,GAAA,IAASR,EAAQQ,EAAA,GAAEhJ,EAAKgJ,EAAA,GAAA,IACjC,OAAA7L,QAAAC,QAAf4F,EAAKwF,GACK1H,QAAQK,EAAS,CACnCqB,UAAWtC,EACXF,MAAAA,KACAxE,KAHEuB,SAAAA,GAAGkM,IAAAA,EAKPhB,EAAOvG,OAASkB,KAAKC,IAAIoF,EAAOvG,OAAQ3E,EAAI2E,SAC5CuH,EAAAhB,EAAOhJ,KAAKe,OAAMtB,KAAIoE,MAAAmG,EAAIlM,EAAIkC,KAAKe,MAAO,EAC5C,CAAC,MAAAhE,GAAAmB,OAAAA,QAAAO,OAAA1B,EAAC,CAAA,KACHR,KAEDoI,WAEgD,OAFhDA,EAAQmB,OAAO,WAAY7E,GAC3B0D,EAAQmB,OAAO,eAAgB,wBAC/BnB,EAAQmB,OAAO,eAAgB,iBAAiB5H,QAAAC,QAE1CD,QAAQ4D,IAAI4E,EAAY/E,IAAI,SAAAzF,GAAC,OAAIA,GAAG,KAAEK,KAE5C,WAAA,OAAW,IAAAiN,SACT/B,EAAAA,UAAUwC,OACRb,EAAWJ,EAAOhJ,KAAKe,MAAM,GAAGnE,OAASoM,EAAOhJ,MAElD,CACEyC,OAAQuG,EAAOvG,OACfkC,QAAAA,GAEF,EACJ,EAAA,CAAC,MAAA5H,GAAAmB,OAAAA,QAAAO,OAAA1B,EAAA,CAAA,GAEL,CAAE,MAAOA,GAKP,OAJA8F,QAAQC,MAAM/F,GAEd6D,EAAOqC,iBAAiBlG,GAExBmB,QAAAC,QAAO,IAAIqL,SAASC,KAAKC,UAAUpG,EAAAA,sBAAsBX,cAAe,CACtEF,OAAQ,IACRkC,QAAAA,IAEJ,CACF,CAAC,MAAA5H,GAAA,OAAAmB,QAAAO,OAAA1B,EACF,CAAA,GAAA,CAAA,MAAAA,GAAA,OAAAmB,QAAAO,OAAA1B,EAAA,CAAA,GACJA,CAAAA,MAAAA,GAAAmB,OAAAA,QAAAO,OAAA1B,EACJ,CAAA,GAAA,EAzQGyJ,EAAkC,OAA5BnC,EAAGzE,EAAI+E,QAAQpG,IAAI,WAAS8F,EAAI,GACtCoB,GAAS,EAEb,GAAIjI,EAAK0M,MAAQ,YAAa1M,EAAK0M,KACjC,IACE,IACIC,EADM,IAAIC,IAAI5D,GACG6D,SAASjI,MAAM,KAAKkH,OAAO,GAAGvE,KAAK,KACxDU,EAASjI,EAAK0M,KAAKI,QAAQC,SAASJ,EACtC,CAAE,MAAOpN,GAGX,MAAWS,EAAK0M,MAAQ,UAAW1M,EAAK0M,OACtCzE,EAASjI,EAAK0M,KAAKM,MAAMhE,IAG3B,IAAIS,EAAM,IAAImD,IAAIxK,EAAIqH,KAElBwD,EAAiC,OAAZnG,EAAG9G,EAAK0M,OAAL5F,OAASA,EAATA,EAAWK,cAAXL,EAAAA,EAAoBS,KAAK,MACjD0F,IAAuBA,GAA6BA,KAAAA,GAAwBrF,QAEhF,IAAIQ,EAAsCH,EACtC,CACE,8BAA+Be,EAC/B,+BAAgC,gBAChC,+BAA8B,sDACP,MAArBiE,EAAAA,EAAyB,IAE3B,yBAA0B,SAC1B,mCAAoC,QAEtC,CAAA,EAEJ,GAAkB,WAAd7K,EAAI8K,OACN,OACExM,QAAAC,QADEsH,EACK,IAAI+D,SAAS,KAAM,CACxB/G,OAAQ,IACRkC,QAASiB,IAIN,IAAI4D,SAAS,KAAM,CAAE/G,OAAQ,OAGtC,IAAIzC,EAAY,KAAK3B,sFAAAuE,CAEjB,WAAA,IAAA+H,EACKlD,EAAAA,UAAUmD,OAAM,OAAA1M,QAAAC,QAAOyB,EAAIiL,QAAMtO,KAAAuO,SAAAA,GAAxC9K,EAAI2K,EAAA5I,KAAG0F,EAASA,UAAAqD,EAA0B,EAC5C,EAAC,WAAWC,IAAAA,EACH,IAAIvB,SACTC,KAAKC,UAAUsB,EAAkBA,mBAAC,CAAEC,QAAS,iBAAkBtI,cAC/D,CAAEF,OAAQ,MACXsI,OAAApN,EAAAoN,EAAAA,CACH,GAAC,OAAA7M,QAAAC,QAAAE,GAAAA,EAAA9B,KAAA8B,EAAA9B,KAAAqB,GAAAA,EAAAS,GAsNH,CAAC,MAAAtB,GAAAmB,OAAAA,QAAAO,OAAA1B,KAEL"}
@@ -1 +1 @@
1
- {"version":3,"file":"rpcMux.d.ts","sourceRoot":"","sources":["../src/rpcMux.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAe9C,eAAO,IAAI,MAAM,GACf,MAAM;IACJ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACpB,GAAG,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG;QAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAA;KAAE,CAAC,CAAC;CACtE,EACD,MAAM;IACJ,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,CACP,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE;QACJ,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE;YACL,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,GAAG,CAAC;SACd,EAAE,CAAC;KACL,KACE,OAAO,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE;YACJ,KAAK,EAAE,GAAG,EAAE,CAAC;SACd,CAAC;KACH,CAAC,CAAC;CACJ,EAAE;;iBASkB,GAAG,KAAG,OAAO,CAAC,GAAG,CAAC;CAsQxC,CAAC"}
1
+ {"version":3,"file":"rpcMux.d.ts","sourceRoot":"","sources":["../src/rpcMux.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAe9C,eAAO,IAAI,MAAM,GACf,MAAM;IACJ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACpB,GAAG,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG;QAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAA;KAAE,CAAC,CAAC;CACtE,EACD,MAAM;IACJ,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,CACP,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE;QACJ,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE;YACL,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,GAAG,CAAC;SACd,EAAE,CAAC;KACL,KACE,OAAO,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE;YACJ,KAAK,EAAE,GAAG,EAAE,CAAC;SACd,CAAC;KACH,CAAC,CAAC;CACJ,EAAE;;iBASkB,GAAG,KAAG,OAAO,CAAC,GAAG,CAAC;CA6QxC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowerdeck/rpc-server",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
package/src/rpcMux.ts CHANGED
@@ -231,7 +231,9 @@ export let rpcMux = (
231
231
  let pathParts = url.pathname.split('/').filter(Boolean);
232
232
  let lastPart = pathParts[pathParts.length - 1];
233
233
 
234
- if (lastPart[0] == '$') {
234
+ let isSingle = lastPart[0] == '$';
235
+
236
+ if (isSingle) {
235
237
  let id = lastPart.slice(1);
236
238
  let rpcIndex = handlerNameToRpcMap.get(id);
237
239
  if (rpcIndex == undefined) {
@@ -300,10 +302,15 @@ export let rpcMux = (
300
302
 
301
303
  await Promise.all(beforeSends.map(s => s()));
302
304
 
303
- return new Response(serialize.encode(resRef.body), {
304
- status: resRef.status,
305
- headers
306
- });
305
+ return new Response(
306
+ serialize.encode(
307
+ isSingle ? resRef.body.calls[0].result : resRef.body
308
+ ),
309
+ {
310
+ status: resRef.status,
311
+ headers
312
+ }
313
+ );
307
314
  }
308
315
  );
309
316
  } catch (e) {