UNPKG

@graphile/supporter

Version:

PostGraphile enhancements for development sponsors

1 lines 13.3 kB
module.exports=function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=10)}([function(e,t){e.exports=require("debug")},function(e,t){e.exports=require("graphql-subscriptions")},function(e,t){e.exports=require("events")},function(e,t){e.exports=require("lodash/mapKeys")},function(e,t){e.exports=require("subscriptions-transport-ws")},function(e,t){e.exports=require("http")},function(e,t){e.exports=require("ws")},function(e,t){e.exports=require("crypto")},function(e){e.exports={a:"0.8.3"}},function(e,t){e.exports=require("url")},function(e,t,r){"use strict";r.r(t);var n=r(1),o=r(2),i=r(0),s=r.n(i),a=r(3),c=r.n(a),l=r(4),u=r(5);function p(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}const f=s()("graphile-build-pg:subscriptions"),d=e=>(e=>Buffer.from(String(e)).toString("base64"))(JSON.stringify(e));var b=function(e,{pubsub:t,pgSubscriptionPrefix:r="postgraphile:",pgSubscriptionAuthorizationFunction:n}){if(!t)return void f("Subscriptions disabled - no pubsub provided");const o={listen:()=>"listen",listenPayload:()=>"ListenPayload"};e.hook("build",e=>e.inflection?e.extend(e,{inflection:e.extend(e.inflection||{},{listen:()=>"listen",listenPayload(){return this.upperCamelCase(`${this.listen()}-payload`)}})}):e),e.hook("GraphQLObjectType:fields",(e,i,{scope:{isRootSubscription:s},fieldWithHooks:a})=>{const{extend:c,newWithHooks:l,pgSql:u,graphql:{GraphQLObjectType:b,GraphQLNonNull:h,GraphQLString:g,GraphQLID:y},getTypeByName:w,$$isQuery:m,pgParseIdentifier:v,resolveNode:S}=i;if(!s)return e;const O=n?v(n):null,P=w("Node"),E=w("Query"),x=i.inflection||o,I=l(b,{name:x.listenPayload(),fields:()=>Object.assign({},{query:{description:"Our root query field type. Allows us to run any query from our subscription payload.",type:E,resolve:()=>m}},P?{relatedNode:a("relatedNode",({getDataFromParsedResolveInfoFragment:e})=>({type:P,resolve:async(t,r,n,o)=>t.relatedNodeId?await S(t.relatedNodeId,i,{getDataFromParsedResolveInfoFragment:e},{},n,o):null}),{isPgGenericSubscriptionPayloadRelatedNodeField:!0}),relatedNodeId:{type:y}}:null)},{isPgGenericSubscriptionPayloadType:!0}),j=x.listen();return c(e,{[j]:a(j,()=>({type:new h(I),args:{topic:{type:new h(g)}},subscribe:async(e,n,o,i)=>{const{pgClient:s}=o,a=(r||"")+n.topic;let c;if(O){const{text:e,values:t}=u.compile(u.query`select unsubscribe_topic from ${u.identifier(O.namespaceName,O.entityName)}(${u.value(a)}) unsubscribe_topic`),{rows:[[r]]}=await s.query({text:e,values:t,rowMode:"array"});if(!r)throw new Error("You may not subscribe to this topic");c=r}const l=t.asyncIterator(a);if(c){const e=t.asyncIterator(c);e.next().then(()=>{f("Unsubscribe triggered on channel %s",c),l.return(),e.return()})}return l},resolve:async(e,t,r,n)=>{const o=function(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},n=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(r).filter(function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable}))),n.forEach(function(t){p(e,t,r[t])})}return e}({},e);if(P&&e&&e.__node__){const t=d(e.__node__);o.relatedNodeId=t}return o}}),{isPgGenericSubscriptionRootField:!0})})})};function h(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}const g=s()("graphile-build-pg:subscriptions");var y=function(e,{pubsub:t}){t?e.hook("GraphQLObjectType:fields:field",(e,r,n)=>{const{extend:o}=r,{scope:{isRootSubscription:i,fieldDirectives:s}}=n;if(!i)return e;if(!s)return e;const{pgSubscription:a}=s;if(!a)return e;const{topic:c,unsubscribeTopic:l}=a;return c?o(e,function(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},n=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(r).filter(function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable}))),n.forEach(function(t){h(e,t,r[t])})}return e}({subscribe:async(e,r,n,o)=>{const i="function"==typeof c?await c(r,n,o):c;if(!i)throw new Error("Cannot subscribe at this time");if("string"!=typeof i)throw new Error("Invalid topic provided to pgSubscription");const s="function"==typeof l?await l(r,n,o):l,a=t.asyncIterator(i);if(s){const e=(Array.isArray(s)?s:[s]).map(e=>{const r=t.asyncIterator(e);return r.topic=e,r});e.forEach(t=>{t.next().then(()=>{g("Unsubscribe triggered on channel %s",t.topic),a.return(),e.forEach(e=>e.return())})})}return a}},e.resolve?null:{resolve:e=>e})):e}):g("Subscriptions disabled - no pubsub provided")},w=r(6),m=r(7),v=r(8),S=r(9);function O(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},n=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(r).filter(function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable}))),n.forEach(function(t){P(e,t,r[t])})}return e}function P(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}r.d(t,"enhanceHttpServerWithSubscriptions",function(){return L});let E=!1;const x=s()("postgraphile:subscriptions"),I=e=>Buffer.from(String(e),"base64"),j="-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEiapOpoQOUtpoIoJjCZPyAiX51aIt\nwMJFV4OIttJG7N7EVGOAsgLddp02m8M35S82aHwCHW/AqeBbDpcCVvKGsQ==\n-----END PUBLIC KEY-----";function q(e){const t=e||process.env.GRAPHILE_LICENSE;if("string"!=typeof t)throw new Error("You must set the GRAPHILE_LICENSE environmental variable (or `license` library option) to use @graphile/supporter, find out more: https://www.graphile.org/postgraphile/plugins/");let r;const n=I(t);if(n.length>7){if(0==(7&n.readUInt8(n.length-1))){const e=n.readUInt8(n.length-1)>>3,t=n.readUInt8(n.length-2);if(n.length>5+t){const o=n.slice(2,2+t),i=n.slice(2+t,n.length-2);if(0===e){const e=Object(m.createVerify)("SHA256");if(e.write(i),e.end(),e.verify(j,o))try{r=JSON.parse(i.toString("utf8"))}catch(e){throw new Error("Invalid (corrupt) license file")}}}}}if(!r)throw new Error("Invalid license key");const{t:o,g:i,e:s}=r,a=o;if(1!=(1&i))throw new Error("Your license does not cover usage of the @graphile/supporter module");if(s<Date.now())throw new Error("Your Graphile license has expired, please renew it!");if(s<Date.now()+2592e6){const e=(s-Date.now())/864e5;console.error(`\n\n⚠️ ⚠️ ⚠️ \n\nYour Graphile license will expire in ${e>1?e.toFixed(2)+" days":(24*e).toFixed(1)+" hours"}, please renew it!\n\n⚠️ ⚠️ ⚠️ \n\n`)}return{licensedTo:a}}let _,N;t.default={init(e,{version:t,graphql:r}){if(!E){E=!0;const e=t.split(".");if(parseInt(e[0],10)<4)throw new Error(`Unsupported version ${t}`);if(!r)throw new Error("Incompatible version of PostGraphile; 'graphql' not available on 'check' hook.");({execute:_,subscribe:N}=r)}},"cli:flags:add:schema":e=>(e("-S, --simple-subscriptions","⚡️[experimental] add simple subscription support"),e("--subscription-authorization-function [schemaDotFunctionName]","⚡️[experimental] PG function to call to check user is allowed to subscribe"),e),"cli:library:options"(e,{config:t,cliOptions:r}){const{simpleSubscriptions:n=!1,subscriptionAuthorizationFunction:o=null}=O({},t.options,r);return O({},e,{simpleSubscriptions:n,subscriptionAuthorizationFunction:o})},"postgraphile:middleware"(e,{options:t}){let r=!1;const n=(...n)=>{if(!r){r=!0;const[o,i,s]=n;let a;if("function"==typeof i){const[e,t]=[o,i];a=e.req}else if("function"==typeof s){const[e,t,r]=[o,i,s];a=e}else{const[e,t]=[o,i];a=e}const c=a&&a.connection&&a.connection.server;c?L(c,e,t):console.warn("Failed to find server to add websocket listener to, you'll need to call `enhanceHttpServerWithSubscriptions` manually")}return e(...n)};return Object.assign(n,e),n},"cli:server:created":(e,{options:t,middleware:r})=>(r.getGraphQLSchema&&L(e,r,t),e),"cli:greeting"(e,{options:t,port:r,chalk:n,middleware:o}){const{graphqlRoute:i,host:s="localhost",simpleSubscriptions:a,license:c}=t,{licensedTo:l}=q(c);return[...e,`@graphile/supporter: v${v.a}, licensed to '${l}'`," Thanks for supporting PostGraphile! 🙏",a&&o.getGraphQLSchema?`Subscriptions support enabled at ${n.underline(`ws://${s}:${r}${i}`)}`:null]},"postgraphile:options"(e,{pgPool:t}){if(!E)throw new Error("To use this plugin you must upgrade to PostGraphile 4.0.0-rc.3 or higher");q(e.license);const r=new o.EventEmitter,{simpleSubscriptions:i,subscriptionAuthorizationFunction:s}=e,a=new n.PubSub({eventEmitter:r}),c=function(e){let t;if(e.payload)try{t=JSON.parse(e.payload)}catch(e){x("Failed to parse payload JSON"),x(e)}a.publish(e.channel,t)};let l;const u=function(){l&&l.removeListener("notification",c),l=null},p=function(e,t){const r="LISTEN "+e.escapeIdentifier(t);return e.query(r).then(()=>null)},f={},d=r.addListener;r.addListener=function(e,t){var r;return f[r=e]=(f[r]||0)+1,1===f[r]&&l&&p(l,r),d.call(this,e,t)};const h=r.removeListener;r.removeListener=function(e,t){var r;return f[r=e]=(f[r]||1)-1,0===f[r]&&l&&function(e,t){const r="UNLISTEN "+e.escapeIdentifier(t);e.query(r).then(()=>null)}(l,r),h.call(this,e,t)};const g=async function(){let e;try{e=await t.connect()}catch(e){return void setTimeout(g,1e3)}(l=e).addListener("notification",c);const r=Object.entries(f).filter(([e,t])=>t>0).map(([e])=>e);try{await Promise.all(r.map(t=>p(e,t)))}catch(e){u(),g()}};return g(),t.on("remove",e=>{e===l&&(u(),t.ending||g())}),O({},e,{graphileBuildOptions:O({},e.graphileBuildOptions,{pubsub:a,pgSubscriptionAuthorizationFunction:s}),appendPlugins:[...e.appendPlugins||[],y,...i?[b]:[]]})},withPostGraphileContext:e=>async(t,r)=>{if(t.singleStatement){const n={query(r,n,o){if(r&&"object"==typeof r){if(n||o)throw new Error("Incompatible call to singleStatement - expected no callback")}else{if("string"!=typeof r)throw new Error("Incompatible call to singleStatement - bad query");if(n&&"object"!=typeof n)throw new Error("Incompatible call to singleStatement - bad values");if(o)throw new Error("Incompatible call to singleStatement - expected to return promise")}return e(O({},t,{singleStatement:!1}),({pgClient:e})=>e.query(r,n))}};return await r({pgClient:n})}return e(t,r)}};async function L(e,t,r,n){if(!_)throw new Error("The plugin must be initialised before you call enhanceHttpServerWithSubscriptions.");if(e.__postgraphileSubscriptionsEnabled)return;e.__postgraphileSubscriptionsEnabled=!0;const{getGraphQLSchema:o,formatError:i,withPostGraphileContextFromReqRes:s}=t,a=r.graphqlRoute||"/graphql",p=await o(),f=r.handleErrors||(e=>e.map(i)),d={},b=e=>{const t=d[e];t&&t.resolve()},h=(e,t)=>{b(t);const r=(()=>{let e,t;const r=new Promise((r,n)=>{e=r,t=n});return r.resolve=e,r.reject=t,r})();return r.context=e,d[t]=r,r},g=async e=>{const{__postgraphileReq:t}=e;if(!t)throw new Error("req could not be extracted");let n=e.__postgraphileRes;if(t.res)throw new Error("Please get in touch with Benjie; we weren't expecting req.res to be present but we want to reserve it for future usage.");return n||((n=new u.ServerResponse(t)).writeHead=(t=>{t&&t>200&&(console.error(`Something used 'writeHead' to write a '${t}' error for websockets - check the middleware you're passing!`),e.close())}),await(async(e=[],t,r)=>{for(const n of e)await new Promise((e,o)=>{n(t,r,t=>t?o(t):e())})})(r.websocketMiddlewares||r.middlewares,t,n),e.__postgraphileRes=n),{req:t,res:n}},y=new w.Server({noServer:!0});e.on("upgrade",(e,t,r)=>{const n=e.originalUrl||e.url;Object(S.parse)(n).pathname===a&&y.handleUpgrade(e,t,r,t=>{y.emit("connection",t,e)})});const m=l.SubscriptionServer.create(O({schema:p,execute:_,subscribe:N,onConnect(e,t,r){const{socket:n,request:o}=r;if(!o)throw new Error("No request!");o.connectionParams=e;const i=Object.keys(e).reduce((t,r)=>(t[r.toLowerCase()]=e[r],t),{});o.normalizedConnectionParams=i,n.__postgraphileReq=o,!o.headers.authorization&&i.authorization&&(o.headers.authorization=String(i.authorization)),n.postgraphileHeaders=Object.assign({},c()(e,(e,t)=>t.toLowerCase()),o.headers)},async onOperation(e,t,r){const n=e.id,i=await((e,t)=>new Promise((r,n)=>{g(e).then(({req:e,res:n})=>s(e,n,{singleStatement:!0},e=>{const n=h(e,t);return r(n.context),n})).then(null,n)}))(r,n);m.schema=await o(),Object.assign(t.context,i);const{req:a,res:c}=await g(r);return t.formatResponse=((e,t)=>(e.errors&&(e.errors=f(e.errors,a,c)),e)),t},onOperationComplete(e,t){b(t)}},n),y)}}]);