From 41a5d14fd882487ae40af2990d0b0de2c8a788db Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 18 Sep 2019 00:58:27 +0200 Subject: [PATCH] fix --- lib/RPCaller.min.js | 19 ++ lib/src/backend/RPCSocketServer.d.ts | 96 ++++++ lib/src/backend/RPCSocketServer.js | 152 +++++++++ lib/src/frontend/RPCaller.d.ts | 20 ++ lib/src/frontend/RPCaller.js | 71 +++++ lib/test/test.d.ts | 1 + lib/test/test.js | 19 ++ node_modules/.bin/uuid | 1 + node_modules/uuid/AUTHORS | 5 + node_modules/uuid/CHANGELOG.md | 112 +++++++ node_modules/uuid/LICENSE.md | 21 ++ node_modules/uuid/README.md | 293 ++++++++++++++++++ node_modules/uuid/bin/uuid | 65 ++++ node_modules/uuid/index.js | 8 + node_modules/uuid/lib/bytesToUuid.js | 24 ++ node_modules/uuid/lib/md5-browser.js | 216 +++++++++++++ node_modules/uuid/lib/md5.js | 25 ++ node_modules/uuid/lib/rng-browser.js | 34 ++ node_modules/uuid/lib/rng.js | 8 + node_modules/uuid/lib/sha1-browser.js | 89 ++++++ node_modules/uuid/lib/sha1.js | 25 ++ node_modules/uuid/lib/v35.js | 57 ++++ node_modules/uuid/package.json | 96 ++++++ node_modules/uuid/v1.js | 109 +++++++ node_modules/uuid/v3.js | 4 + node_modules/uuid/v4.js | 29 ++ node_modules/uuid/v5.js | 3 + package-lock.json | 5 + package.json | 9 +- .../{RPCExporter.ts => RPCSocketServer.ts} | 113 ++++++- src/frontend/{RPCallable.ts => RPCaller.ts} | 29 +- src/frontend/webpack.prod.js | 12 +- test/test.ts | 19 ++ tsconfig.json | 4 +- 34 files changed, 1758 insertions(+), 35 deletions(-) create mode 100644 lib/RPCaller.min.js create mode 100644 lib/src/backend/RPCSocketServer.d.ts create mode 100644 lib/src/backend/RPCSocketServer.js create mode 100644 lib/src/frontend/RPCaller.d.ts create mode 100644 lib/src/frontend/RPCaller.js create mode 100644 lib/test/test.d.ts create mode 100644 lib/test/test.js create mode 120000 node_modules/.bin/uuid create mode 100644 node_modules/uuid/AUTHORS create mode 100644 node_modules/uuid/CHANGELOG.md create mode 100644 node_modules/uuid/LICENSE.md create mode 100644 node_modules/uuid/README.md create mode 100755 node_modules/uuid/bin/uuid create mode 100644 node_modules/uuid/index.js create mode 100644 node_modules/uuid/lib/bytesToUuid.js create mode 100644 node_modules/uuid/lib/md5-browser.js create mode 100644 node_modules/uuid/lib/md5.js create mode 100644 node_modules/uuid/lib/rng-browser.js create mode 100644 node_modules/uuid/lib/rng.js create mode 100644 node_modules/uuid/lib/sha1-browser.js create mode 100644 node_modules/uuid/lib/sha1.js create mode 100644 node_modules/uuid/lib/v35.js create mode 100644 node_modules/uuid/package.json create mode 100644 node_modules/uuid/v1.js create mode 100644 node_modules/uuid/v3.js create mode 100644 node_modules/uuid/v4.js create mode 100644 node_modules/uuid/v5.js rename src/backend/{RPCExporter.ts => RPCSocketServer.ts} (54%) rename src/frontend/{RPCallable.ts => RPCaller.ts} (80%) create mode 100644 test/test.ts diff --git a/lib/RPCaller.min.js b/lib/RPCaller.min.js new file mode 100644 index 0000000..d16e45a --- /dev/null +++ b/lib/RPCaller.min.js @@ -0,0 +1,19 @@ +!function(t,e){for(var r in e)t[r]=e[r]}(exports,function(t){var e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)r.d(n,o,function(e){return t[e]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=6)}([function(t,e,r){"use strict"; +/*! + * assert.js - assertions for javascript + * Copyright (c) 2018, Christopher Jeffrey (MIT License). + * https://github.com/chjj/bsert + */class n extends Error{constructor(t){"string"==typeof t&&(t={message:t}),null!==t&&"object"==typeof t||(t={});let e=null,r="fail",n=Boolean(t.generatedMessage);var o;if(null!=t.message&&(e="string"==typeof(o=t.message)?o:E(o)?d(o):p(o)),"string"==typeof t.operator&&(r=t.operator),null==e){if("fail"===r)e="Assertion failed.";else{e=`${p(t.actual)} ${r} ${p(t.expected)}`}n=!0}super(e);let s=this.constructor;"function"==typeof t.stackStartFunction?s=t.stackStartFunction:"function"==typeof t.stackStartFn&&(s=t.stackStartFn),this.type="AssertionError",this.name="AssertionError [ERR_ASSERTION]",this.code="ERR_ASSERTION",this.generatedMessage=n,this.actual=t.actual,this.expected=t.expected,this.operator=r,Error.captureStackTrace&&Error.captureStackTrace(this,s)}}function o(t,e){if(!t){let r=!1;if(0===arguments.length)e="No value argument passed to `assert()`.",r=!0;else if(null==e)e="Assertion failed.",r=!0;else if(E(e))throw e;throw new n({message:e,actual:t,expected:!0,operator:"==",generatedMessage:r,stackStartFn:o})}}function s(t,e,r){if(!Object.is(t,e)){if(E(r))throw r;throw new n({message:r,actual:t,expected:e,operator:"strictEqual",stackStartFn:s})}}function i(t,e,r){if(Object.is(t,e)){if(E(r))throw r;throw new n({message:r,actual:t,expected:e,operator:"notStrictEqual",stackStartFn:i})}}function a(t,e,r){"string"==typeof e&&(r=e,e=void 0);let o=!1,s=null;l("function"==typeof t,"func","function");try{t()}catch(t){o=!0,s=t}if(o){if(g(s,e,r,a)){let t=!1;throw null==r&&(r="Got unwanted exception.",t=!0),new n({message:r,actual:s,expected:e,operator:"doesNotThrow",generatedMessage:t,stackStartFn:a})}throw s}}async function h(t,e,r){"string"==typeof e&&(r=e,e=void 0);let o=!1,s=null;"function"!=typeof t&&l(O(t),"func","promise");try{O(t)?await t:await t()}catch(t){o=!0,s=t}if(!o){let t=!1;throw null==r&&(r="Missing expected rejection.",t=!0),new n({message:r,actual:void 0,expected:e,operator:"rejects",generatedMessage:t,stackStartFn:h})}if(!g(s,e,r,h))throw s}async function u(t,e,r){"string"==typeof e&&(r=e,e=void 0);let o=!1,s=null;"function"!=typeof t&&l(O(t),"func","promise");try{O(t)?await t:await t()}catch(t){o=!0,s=t}if(o){if(g(s,e,r,u)){let t=!1;throw null==r&&(r="Got unwanted rejection.",t=!0),new n({message:r,actual:void 0,expected:e,operator:"doesNotReject",generatedMessage:t,stackStartFn:u})}throw s}}function c(t,e,r){if(!y(t,e,!1)){if(E(r))throw r;throw new n({message:r,actual:t,expected:e,operator:"deepStrictEqual",stackStartFn:c})}}function f(t,e,r){if(y(t,e,!0)){if(E(r))throw r;throw new n({message:r,actual:t,expected:e,operator:"notDeepStrictEqual",stackStartFn:f})}}function l(t,e,r){if(!t){let t;t=null==e?"Invalid type for parameter.":null==r?`Invalid type for "${e}".`:`"${e}" must be a(n) ${r}.`;const n=new TypeError(t);throw Error.captureStackTrace&&Error.captureStackTrace(n,l),n}}function p(t){switch(typeof t){case"undefined":return"undefined";case"object":return null===t?"null":`[${function(t){const e=function(t){return v(t).slice(8,-1)}(t);if(null==t)return e;if("Object"!==e&&"Error"!==e)return e;let r,n;try{r=t.constructor}catch(t){}if(null==r)return e;try{n=r.name}catch(t){return e}return"string"!=typeof n||0===n.length?e:n}(t)}]`;case"boolean":case"number":return`${t}`;case"string":return t.length>80&&(t=`${t.substring(0,77)}...`),JSON.stringify(t);case"symbol":return d(t);case"function":return`[${function(t){let e;try{e=t.name}catch(t){}return"string"!=typeof e||0===e.length?"Function":`Function: ${e}`}(t)}]`;case"bigint":return`${t}n`;default:return`[${typeof t}]`}}function d(t){try{return String(t)}catch(t){return"Object"}}function g(t,e,r,o){if(null==e)return!0;if(S(e))return e.test(t);if("function"!=typeof e){if(o===a||o===u)throw new TypeError('"expected" must not be an object.');if("object"!=typeof e)throw new TypeError('"expected" must be an object.');let s=!1;if(null==r){r=`Missing expected ${o===h?"rejection":"exception"}.`,s=!0}if(null==t||"object"!=typeof t)throw new n({actual:t,expected:e,message:r,operator:o.name,generatedMessage:s,stackStartFn:o});const i=Object.keys(e);if(E(e)&&i.push("name","message"),0===i.length)throw new TypeError('"expected" may not be an empty object.');for(const a of i){const i=e[a],h=t[a];if(("string"!=typeof h||!S(i)||!i.test(h))&&!(a in t&&y(h,i,!1)))throw new n({actual:t,expected:e,message:r,operator:o.name,generatedMessage:s,stackStartFn:o})}return!0}return void 0!==e.prototype&&t instanceof e||!Error.isPrototypeOf(e)&&!0===e.call({},t)}function y(t,e,r){try{return m(t,e,null)}catch(t){return r}}function m(t,e,r){if(Object.is(t,e))return!0;if(!A(t)||!A(e))return!1;if(v(t)!==v(e))return!1;if(Object.getPrototypeOf(t)!==Object.getPrototypeOf(e))return!1;if(b(t)&&b(e))return t.equals(e);if(t instanceof Date)return Object.is(t.getTime(),e.getTime());if(S(t))return t.source===e.source&&t.global===e.global&&t.multiline===e.multiline&&t.lastIndex===e.lastIndex&&t.ignoreCase===e.ignoreCase;if(E(t)&&t.message!==e.message)return!1;if(function(t){return t instanceof ArrayBuffer}(t)&&(t=new Uint8Array(t),e=new Uint8Array(e)),function(t){return ArrayBuffer.isView(t)}(t)&&!b(t)){if(b(e))return!1;const r=new Uint8Array(t.buffer),n=new Uint8Array(e.buffer);if(r.length!==n.length)return!1;for(let t=0;t>>1?null:o}return e}o.AssertionError=n,o.assert=o,o.strict=o,o.ok=o,o.equal=s,o.notEqual=i,o.strictEqual=s,o.notStrictEqual=i,o.fail=function t(e){let r=!1;if(E(e))throw e;throw null==e&&(e="Assertion failed.",r=!0),new n({message:e,actual:!1,expected:!0,operator:"fail",generatedMessage:r,stackStartFn:t})},o.throws=function t(e,r,o){"string"==typeof r&&(o=r,r=void 0);let s=!1,i=null;l("function"==typeof e,"func","function");try{e()}catch(t){s=!0,i=t}if(!s){let e=!1;throw null==o&&(o="Missing expected exception.",e=!0),new n({message:o,actual:void 0,expected:r,operator:"throws",generatedMessage:e,stackStartFn:t})}if(!g(i,r,o,t))throw i},o.doesNotThrow=a,o.rejects=h,o.doesNotReject=u,o.ifError=function t(e){if(null!=e){let r="ifError got unwanted exception: ";throw"object"==typeof e&&"string"==typeof e.message?0===e.message.length&&e.constructor?r+=e.constructor.name:r+=e.message:r+=p(e),new n({message:r,actual:e,expected:null,operator:"ifError",generatedMessage:!0,stackStartFn:t})}},o.deepEqual=c,o.notDeepEqual=f,o.deepStrictEqual=c,o.notDeepStrictEqual=f,o.bufferEqual=function t(e,r,o,s){if(R(o)||(s=o,o=null),null==o&&(o="hex"),r=_(e,r,o),l(b(e),"actual","buffer"),l(b(r),"expected","buffer"),e!==r&&!e.equals(r)){if(E(s))throw s;throw new n({message:s,actual:e.toString(o),expected:r.toString(o),operator:"bufferEqual",stackStartFn:t})}},o.notBufferEqual=function t(e,r,o,s){if(R(o)||(s=o,o=null),null==o&&(o="hex"),r=_(e,r,o),l(b(e),"actual","buffer"),l(b(r),"expected","buffer"),e===r||e.equals(r)){if(E(s))throw s;throw new n({message:s,actual:e.toString(o),expected:r.toString(o),operator:"notBufferEqual",stackStartFn:t})}},o.enforce=l,o.range=function t(e,r){if(!e){const e=new RangeError(null!=r?`"${r}" is out of range.`:"Parameter is out of range.");throw Error.captureStackTrace&&Error.captureStackTrace(e,t),e}},t.exports=o},function(t,e,r){"use strict";(function(t){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ +var n=r(10),o=r(11),s=r(12);function i(){return h.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function a(t,e){if(i()=i())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i().toString(16)+" bytes");return 0|t}function d(t,e){if(h.isBuffer(t))return t.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!=typeof t&&(t=""+t);var r=t.length;if(0===r)return 0;for(var n=!1;;)switch(e){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":case void 0:return F(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return q(t).length;default:if(n)return F(t).length;e=(""+e).toLowerCase(),n=!0}}function g(t,e,r){var n=!1;if((void 0===e||e<0)&&(e=0),e>this.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(e>>>=0))return"";for(t||(t="utf8");;)switch(t){case"hex":return j(this,e,r);case"utf8":case"utf-8":return _(this,e,r);case"ascii":return k(this,e,r);case"latin1":case"binary":return T(this,e,r);case"base64":return R(this,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return C(this,e,r);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}function y(t,e,r){var n=t[e];t[e]=t[r],t[r]=n}function m(t,e,r,n,o){if(0===t.length)return-1;if("string"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),r=+r,isNaN(r)&&(r=o?0:t.length-1),r<0&&(r=t.length+r),r>=t.length){if(o)return-1;r=t.length-1}else if(r<0){if(!o)return-1;r=0}if("string"==typeof e&&(e=h.from(e,n)),h.isBuffer(e))return 0===e.length?-1:w(t,e,r,n,o);if("number"==typeof e)return e&=255,h.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(t,e,r):Uint8Array.prototype.lastIndexOf.call(t,e,r):w(t,[e],r,n,o);throw new TypeError("val must be string, number or Buffer")}function w(t,e,r,n,o){var s,i=1,a=t.length,h=e.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(t.length<2||e.length<2)return-1;i=2,a/=2,h/=2,r/=2}function u(t,e){return 1===i?t[e]:t.readUInt16BE(e*i)}if(o){var c=-1;for(s=r;sa&&(r=a-h),s=r;s>=0;s--){for(var f=!0,l=0;lo&&(n=o):n=o;var s=e.length;if(s%2!=0)throw new TypeError("Invalid hex string");n>s/2&&(n=s/2);for(var i=0;i>8,o=r%256,s.push(o),s.push(n);return s}(e,t.length-r),t,r,n)}function R(t,e,r){return 0===e&&r===t.length?n.fromByteArray(t):n.fromByteArray(t.slice(e,r))}function _(t,e,r){r=Math.min(t.length,r);for(var n=[],o=e;o239?4:u>223?3:u>191?2:1;if(o+f<=r)switch(f){case 1:u<128&&(c=u);break;case 2:128==(192&(s=t[o+1]))&&(h=(31&u)<<6|63&s)>127&&(c=h);break;case 3:s=t[o+1],i=t[o+2],128==(192&s)&&128==(192&i)&&(h=(15&u)<<12|(63&s)<<6|63&i)>2047&&(h<55296||h>57343)&&(c=h);break;case 4:s=t[o+1],i=t[o+2],a=t[o+3],128==(192&s)&&128==(192&i)&&128==(192&a)&&(h=(15&u)<<18|(63&s)<<12|(63&i)<<6|63&a)>65535&&h<1114112&&(c=h)}null===c?(c=65533,f=1):c>65535&&(c-=65536,n.push(c>>>10&1023|55296),c=56320|1023&c),n.push(c),o+=f}return function(t){var e=t.length;if(e<=P)return String.fromCharCode.apply(String,t);var r="",n=0;for(;n0&&(t=this.toString("hex",0,r).match(/.{2}/g).join(" "),this.length>r&&(t+=" ... ")),""},h.prototype.compare=function(t,e,r,n,o){if(!h.isBuffer(t))throw new TypeError("Argument must be a Buffer");if(void 0===e&&(e=0),void 0===r&&(r=t?t.length:0),void 0===n&&(n=0),void 0===o&&(o=this.length),e<0||r>t.length||n<0||o>this.length)throw new RangeError("out of range index");if(n>=o&&e>=r)return 0;if(n>=o)return-1;if(e>=r)return 1;if(this===t)return 0;for(var s=(o>>>=0)-(n>>>=0),i=(r>>>=0)-(e>>>=0),a=Math.min(s,i),u=this.slice(n,o),c=t.slice(e,r),f=0;fo)&&(r=o),t.length>0&&(r<0||e<0)||e>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var s=!1;;)switch(n){case"hex":return v(this,t,e,r);case"utf8":case"utf-8":return b(this,t,e,r);case"ascii":return E(this,t,e,r);case"latin1":case"binary":return A(this,t,e,r);case"base64":return O(this,t,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,t,e,r);default:if(s)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),s=!0}},h.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var P=4096;function k(t,e,r){var n="";r=Math.min(t.length,r);for(var o=e;on)&&(r=n);for(var o="",s=e;sr)throw new RangeError("Trying to access beyond buffer length")}function N(t,e,r,n,o,s){if(!h.isBuffer(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(e>o||et.length)throw new RangeError("Index out of range")}function I(t,e,r,n){e<0&&(e=65535+e+1);for(var o=0,s=Math.min(t.length-r,2);o>>8*(n?o:1-o)}function B(t,e,r,n){e<0&&(e=4294967295+e+1);for(var o=0,s=Math.min(t.length-r,4);o>>8*(n?o:3-o)&255}function U(t,e,r,n,o,s){if(r+n>t.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function L(t,e,r,n,s){return s||U(t,0,r,4),o.write(t,e,r,n,23,4),r+4}function M(t,e,r,n,s){return s||U(t,0,r,8),o.write(t,e,r,n,52,8),r+8}h.prototype.slice=function(t,e){var r,n=this.length;if((t=~~t)<0?(t+=n)<0&&(t=0):t>n&&(t=n),(e=void 0===e?n:~~e)<0?(e+=n)<0&&(e=0):e>n&&(e=n),e0&&(o*=256);)n+=this[t+--e]*o;return n},h.prototype.readUInt8=function(t,e){return e||x(t,1,this.length),this[t]},h.prototype.readUInt16LE=function(t,e){return e||x(t,2,this.length),this[t]|this[t+1]<<8},h.prototype.readUInt16BE=function(t,e){return e||x(t,2,this.length),this[t]<<8|this[t+1]},h.prototype.readUInt32LE=function(t,e){return e||x(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},h.prototype.readUInt32BE=function(t,e){return e||x(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},h.prototype.readIntLE=function(t,e,r){t|=0,e|=0,r||x(t,e,this.length);for(var n=this[t],o=1,s=0;++s=(o*=128)&&(n-=Math.pow(2,8*e)),n},h.prototype.readIntBE=function(t,e,r){t|=0,e|=0,r||x(t,e,this.length);for(var n=e,o=1,s=this[t+--n];n>0&&(o*=256);)s+=this[t+--n]*o;return s>=(o*=128)&&(s-=Math.pow(2,8*e)),s},h.prototype.readInt8=function(t,e){return e||x(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},h.prototype.readInt16LE=function(t,e){e||x(t,2,this.length);var r=this[t]|this[t+1]<<8;return 32768&r?4294901760|r:r},h.prototype.readInt16BE=function(t,e){e||x(t,2,this.length);var r=this[t+1]|this[t]<<8;return 32768&r?4294901760|r:r},h.prototype.readInt32LE=function(t,e){return e||x(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},h.prototype.readInt32BE=function(t,e){return e||x(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},h.prototype.readFloatLE=function(t,e){return e||x(t,4,this.length),o.read(this,t,!0,23,4)},h.prototype.readFloatBE=function(t,e){return e||x(t,4,this.length),o.read(this,t,!1,23,4)},h.prototype.readDoubleLE=function(t,e){return e||x(t,8,this.length),o.read(this,t,!0,52,8)},h.prototype.readDoubleBE=function(t,e){return e||x(t,8,this.length),o.read(this,t,!1,52,8)},h.prototype.writeUIntLE=function(t,e,r,n){(t=+t,e|=0,r|=0,n)||N(this,t,e,r,Math.pow(2,8*r)-1,0);var o=1,s=0;for(this[e]=255&t;++s=0&&(s*=256);)this[e+o]=t/s&255;return e+r},h.prototype.writeUInt8=function(t,e,r){return t=+t,e|=0,r||N(this,t,e,1,255,0),h.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),this[e]=255&t,e+1},h.prototype.writeUInt16LE=function(t,e,r){return t=+t,e|=0,r||N(this,t,e,2,65535,0),h.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):I(this,t,e,!0),e+2},h.prototype.writeUInt16BE=function(t,e,r){return t=+t,e|=0,r||N(this,t,e,2,65535,0),h.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):I(this,t,e,!1),e+2},h.prototype.writeUInt32LE=function(t,e,r){return t=+t,e|=0,r||N(this,t,e,4,4294967295,0),h.TYPED_ARRAY_SUPPORT?(this[e+3]=t>>>24,this[e+2]=t>>>16,this[e+1]=t>>>8,this[e]=255&t):B(this,t,e,!0),e+4},h.prototype.writeUInt32BE=function(t,e,r){return t=+t,e|=0,r||N(this,t,e,4,4294967295,0),h.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):B(this,t,e,!1),e+4},h.prototype.writeIntLE=function(t,e,r,n){if(t=+t,e|=0,!n){var o=Math.pow(2,8*r-1);N(this,t,e,r,o-1,-o)}var s=0,i=1,a=0;for(this[e]=255&t;++s>0)-a&255;return e+r},h.prototype.writeIntBE=function(t,e,r,n){if(t=+t,e|=0,!n){var o=Math.pow(2,8*r-1);N(this,t,e,r,o-1,-o)}var s=r-1,i=1,a=0;for(this[e+s]=255&t;--s>=0&&(i*=256);)t<0&&0===a&&0!==this[e+s+1]&&(a=1),this[e+s]=(t/i>>0)-a&255;return e+r},h.prototype.writeInt8=function(t,e,r){return t=+t,e|=0,r||N(this,t,e,1,127,-128),h.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[e]=255&t,e+1},h.prototype.writeInt16LE=function(t,e,r){return t=+t,e|=0,r||N(this,t,e,2,32767,-32768),h.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):I(this,t,e,!0),e+2},h.prototype.writeInt16BE=function(t,e,r){return t=+t,e|=0,r||N(this,t,e,2,32767,-32768),h.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):I(this,t,e,!1),e+2},h.prototype.writeInt32LE=function(t,e,r){return t=+t,e|=0,r||N(this,t,e,4,2147483647,-2147483648),h.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8,this[e+2]=t>>>16,this[e+3]=t>>>24):B(this,t,e,!0),e+4},h.prototype.writeInt32BE=function(t,e,r){return t=+t,e|=0,r||N(this,t,e,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),h.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):B(this,t,e,!1),e+4},h.prototype.writeFloatLE=function(t,e,r){return L(this,t,e,!0,r)},h.prototype.writeFloatBE=function(t,e,r){return L(this,t,e,!1,r)},h.prototype.writeDoubleLE=function(t,e,r){return M(this,t,e,!0,r)},h.prototype.writeDoubleBE=function(t,e,r){return M(this,t,e,!1,r)},h.prototype.copy=function(t,e,r,n){if(r||(r=0),n||0===n||(n=this.length),e>=t.length&&(e=t.length),e||(e=0),n>0&&n=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),t.length-e=0;--o)t[o+e]=this[o+r];else if(s<1e3||!h.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,r=void 0===r?this.length:r>>>0,t||(t=0),"number"==typeof t)for(s=e;s55295&&r<57344){if(!o){if(r>56319){(e-=3)>-1&&s.push(239,191,189);continue}if(i+1===n){(e-=3)>-1&&s.push(239,191,189);continue}o=r;continue}if(r<56320){(e-=3)>-1&&s.push(239,191,189),o=r;continue}r=65536+(o-55296<<10|r-56320)}else o&&(e-=3)>-1&&s.push(239,191,189);if(o=null,r<128){if((e-=1)<0)break;s.push(r)}else if(r<2048){if((e-=2)<0)break;s.push(r>>6|192,63&r|128)}else if(r<65536){if((e-=3)<0)break;s.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((e-=4)<0)break;s.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return s}function q(t){return n.toByteArray(function(t){if((t=function(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}(t).replace(D,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function $(t,e,r,n){for(var o=0;o=e.length||o>=t.length);++o)e[o+r]=t[o];return o}}).call(this,r(2))},function(t,e){var r;r=function(){return this}();try{r=r||new Function("return this")()}catch(t){"object"==typeof window&&(r=window)}t.exports=r},function(t,e,r){"use strict";var n,o="object"==typeof Reflect?Reflect:null,s=o&&"function"==typeof o.apply?o.apply:function(t,e,r){return Function.prototype.apply.call(t,e,r)};n=o&&"function"==typeof o.ownKeys?o.ownKeys:Object.getOwnPropertySymbols?function(t){return Object.getOwnPropertyNames(t).concat(Object.getOwnPropertySymbols(t))}:function(t){return Object.getOwnPropertyNames(t)};var i=Number.isNaN||function(t){return t!=t};function a(){a.init.call(this)}t.exports=a,a.EventEmitter=a,a.prototype._events=void 0,a.prototype._eventsCount=0,a.prototype._maxListeners=void 0;var h=10;function u(t){return void 0===t._maxListeners?a.defaultMaxListeners:t._maxListeners}function c(t,e,r,n){var o,s,i,a;if("function"!=typeof r)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof r);if(void 0===(s=t._events)?(s=t._events=Object.create(null),t._eventsCount=0):(void 0!==s.newListener&&(t.emit("newListener",e,r.listener?r.listener:r),s=t._events),i=s[e]),void 0===i)i=s[e]=r,++t._eventsCount;else if("function"==typeof i?i=s[e]=n?[r,i]:[i,r]:n?i.unshift(r):i.push(r),(o=u(t))>0&&i.length>o&&!i.warned){i.warned=!0;var h=new Error("Possible EventEmitter memory leak detected. "+i.length+" "+String(e)+" listeners added. Use emitter.setMaxListeners() to increase limit");h.name="MaxListenersExceededWarning",h.emitter=t,h.type=e,h.count=i.length,a=h,console&&console.warn&&console.warn(a)}return t}function f(){for(var t=[],e=0;e0&&(i=e[0]),i instanceof Error)throw i;var a=new Error("Unhandled error."+(i?" ("+i.message+")":""));throw a.context=i,a}var h=o[t];if(void 0===h)return!1;if("function"==typeof h)s(h,this,e);else{var u=h.length,c=g(h,u);for(r=0;r=0;s--)if(r[s]===e||r[s].listener===e){i=r[s].listener,o=s;break}if(o<0)return this;0===o?r.shift():function(t,e){for(;e+1=0;n--)this.removeListener(t,e[n]);return this},a.prototype.listeners=function(t){return p(this,t,!0)},a.prototype.rawListeners=function(t){return p(this,t,!1)},a.listenerCount=function(t,e){return"function"==typeof t.listenerCount?t.listenerCount(e):d.call(t,e)},a.prototype.listenerCount=d,a.prototype.eventNames=function(){return this._eventsCount>0?n(this._events):[]}},function(t,e,r){"use strict";(function(e){t.exports={Client:e.WebSocket||e.MozWebSocket,EventSource:e.EventSource}}).call(this,r(2))},function(t,e,r){"use strict";(function(e){const n=r(0),o=e.alloc(0),s={OPEN:0,CLOSE:1,PING:2,PONG:3,MESSAGE:4,UPGRADE:5,NOOP:6};class i{constructor(t,r,i){n("number"==typeof t),n(t>>>0===t),n(t<=s.NOOP),n("boolean"==typeof i),i?(null==r&&(r=o),n(e.isBuffer(r))):(null==r&&(r=""),n("string"==typeof r)),this.type=t,this.data=r,this.binary=i}toString(){let t="";return this.binary?(t+="b",t+=this.type.toString(10),t+=this.data.toString("base64")):(t+=this.type.toString(10),t+=this.data),t}static fromString(t){n("string"==typeof t);let r,o=t.charCodeAt(0),i=!1;return 98===o?(n(t.length>1),o=t.charCodeAt(1),r=e.from(t.substring(2),"base64"),i=!0):r=t.substring(1),n((o-=48)>=0&&o<=9),n(o<=s.NOOP),new this(o,r,i)}size(){let t=1;return this.binary?t+=this.data.length:t+=e.byteLength(this.data,"utf8"),t}toRaw(){const t=e.allocUnsafe(this.size());return t[0]=this.type,this.binary?this.data.copy(t,1):this.data.length>0&&t.write(this.data,1,"utf8"),t}static fromRaw(t){n(e.isBuffer(t)),n(t.length>0);const r=t[0];return n(r<=s.NOOP),new this(r,t.slice(1),!0)}}i.types=s,i.table=["open","close","ping","pong","message","upgrade","noop"],t.exports=i}).call(this,r(1).Buffer)},function(module,exports,__webpack_require__){"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var bsock=__webpack_require__(7);function stripAfterEquals(t){return t.split("=")[0]}class RPCaller{constructor(t,e,r=!1){this.socket=bsock.connect(t,e,r)}async connect(){(await this.info()).forEach(t=>{let e;switch(t.type){case"call":e=this.callGenerator(t.uniqueName,t.argNames);break;case"hook":e=this.hookGenerator(t.uniqueName,t.argNames);break;case"unhook":e=this.unhookGenerator(t.uniqueName,t.argNames)}null==this[t.owner]&&(this[t.owner]={}),this[t.owner][t.name]=e,this[t.owner][t.name].bind(this)})}async info(){return await this.socket.call("info")}callGenerator(fnName,fnArgs){const headerArgs=fnArgs.join(","),argParams=fnArgs.map(stripAfterEquals).join(",");return eval("( () => async ("+headerArgs+') => { return await this.socket.call("'+fnName+'", '+argParams+")} )()")}hookGenerator(fnName,fnArgs){const headerArgs=fnArgs.join(","),argParams=fnArgs.map(stripAfterEquals).join(",");return eval("( () => async ("+headerArgs+(0!==headerArgs.length?",":"")+' callback) => {\n const r = await this.socket.call("'+fnName+'", '+argParams+")\n if(r.uid != null){\n this.socket.hook(res.uid, callback)\n }\n return res\n } )()")}unhookGenerator(fnName,fnArgs){const headerArgs=fnArgs.join(","),argParams=fnArgs.map(stripAfterEquals).join(",");return 1!=fnArgs.length&&console.error("UnhookFunction",fnName,"specified more than one argument: ("+headerArgs+")"),eval("( () => async ("+headerArgs+') => {\n const r = await this.socket.call("'+fnName+'", '+argParams+")\n this.socket.unhook("+argParams+")\n return res\n } )()")}}exports.RPCaller=RPCaller},function(t,e,r){"use strict";const n=r(4),o=r(8),s=r(9);e.WebSocket=n,e.Server=o,e.server=()=>new o,e.createServer=o.createServer.bind(o),e.attach=o.attach.bind(o),e.Socket=s,e.socket=()=>new s,e.connect=s.connect.bind(s)},function(t,e,r){"use strict";const n=r(3);t.exports=class extends n{constructor(t){super(),this.sockets=new Set,this.channels=new Map,this.mounts=[]}attach(){return this}mount(){}async open(){}async close(){}join(){return!0}leave(){return!0}channel(){return null}to(){}all(){}static attach(t,e){return new this(e).attach(t)}static createServer(t){return new this(t)}}},function(t,e,r){"use strict";(function(e){const n=r(0),o=r(3),s=r(4).Client,i=r(13),a=r(5),h=r(14),u=r(22),c=r(23),f=r(24);class l{constructor(t,e,r){this.resolve=t,this.reject=e,this.time=r}}function p(t){return null!==t&&"number"!=typeof t&&"string"!=typeof t?null:t}function d(t){return"string"!=typeof t?"No message.":t}function g(t){return"string"!=typeof t?null:t}function y(t,e,r){if(!t){const t=new TypeError(`'${e}' must be a(n) ${r}.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,y),t}}t.exports=class extends o{constructor(){super(),this.server=null,this.ws=null,this.protocol="",this.url="ws://127.0.0.1:80/socket.io/?transport=websocket",this.ssl=!1,this.host="127.0.0.1",this.port=80,this.inbound=!1,this.handshake=!1,this.opened=!1,this.connected=!1,this.challenge=!1,this.destroyed=!1,this.reconnection=!0,this.time=0,this.sequence=0,this.pingInterval=25e3,this.pingTimeout=6e4,this.lastPing=0,this.parser=new u,this.binary=!1,this.packet=null,this.timer=null,this.jobs=new Map,this.hooks=new Map,this.channels=new Set,this.events=new o,this.buffer=[],this.admin=!1,this.auth=!1}accept(t,e,r,o){n(!this.ws,"Cannot accept twice."),n(t),n(e),n(r),n(r.remoteAddress),n(null!=r.remotePort),n(o);let s="ws",i=r.remoteAddress,a=r.remotePort;return r.encrypted&&(s="wss"),-1!==i.indexOf(":")&&(i=`[${i}]`),a||(a=0),this.server=t,this.binary=-1===e.url.indexOf("b64=1"),this.url=`${s}://${i}:${a}/socket.io/?transport=websocket`,this.ssl="wss"===s,this.host=r.remoteAddress,this.port=r.remotePort,this.inbound=!0,this.ws=o,this.init(),this}connect(t,e,r,o){n(!this.ws,"Cannot connect twice."),"string"==typeof t&&(o=e,[t,e,r]=h.parseURL(t));let i="ws";r&&(i="wss"),e||(e="127.0.0.1"),n("string"==typeof e),n((65535&t)===t,"Must pass a port."),n(!r||"boolean"==typeof r),n(!o||Array.isArray(o));let a=e;-1!==e.indexOf(":")&&"["!==e[0]&&(a=`[${e}]`);const u=`${i}://${a}:${t}/socket.io/?transport=websocket`;return this.binary=!0,this.url=u,this.ssl=r,this.host=e,this.port=t,this.inbound=!1,this.ws=new s(u,o),this.init(),this}init(){this.protocol=this.ws.protocol,this.time=Date.now(),this.observe(),this.parser.on("error",t=>{this.emit("error",t)}),this.parser.on("frame",async t=>{try{await this.handleFrame(t)}catch(t){this.emit("error",t)}}),this.start()}observe(){const t=this.ws;n(t),t.binaryType="arraybuffer",t.onopen=async()=>{await this.onOpen()},t.onmessage=async t=>{await this.onMessage(t)},t.onerror=async t=>{await this.onError(t)},t.onclose=async t=>{await this.onClose(t)}}async onOpen(){this.destroyed||this.inbound&&(n(!this.opened),n(!this.connected),n(!this.handshake),this.opened=!0,this.handshake=!0,await this.emitAsync("open"),this.sendHandshake(),this.connected=!0,await this.emitAsync("connect"),this.sendConnect())}async emitAsync(t,...e){const r=this.listeners(t);for(const t of r)try{await t(...e)}catch(t){this.emit("error",t)}}async onMessage(t){if(this.destroyed)return;let r;try{r=await function(t){return new Promise((r,n)=>{if("string"!=typeof t)if(t&&"object"==typeof t)if(e.isBuffer(t))r(t);else if(t instanceof ArrayBuffer){const n=e.from(t);r(n)}else if(t.buffer instanceof ArrayBuffer){const n=e.from(t.buffer,t.byteOffset,t.byteLength);r(n)}else{if("undefined"!=typeof Blob&&Blob&&t instanceof Blob){const n=new FileReader;return n.onloadend=()=>{const t=e.from(n.result);r(t)},void n.readAsArrayBuffer(t)}n(new Error("Bad data object."))}else n(new Error("Bad data object."));else r(t)})}(t.data)}catch(t){return void this.emit("error",t)}"string"!=typeof r?this.parser.feedBinary(r):this.parser.feedString(r)}async onError(t){this.destroyed||(this.emit("error",new Error(t.message)),this.inbound?this.destroy():this.close())}async onClose(t){if(this.destroyed)return;if(1e3===t.code||1001===t.code)return this.connected||this.emit("error",new Error("Could not connect.")),this.inbound?void this.destroy():void this.close();const e=c[t.code]||"UNKNOWN_CODE",r=t.reason||"Unknown reason",n=new Error(`Websocket Closed: ${r} (code=${e}).`);n.reason=t.reason||"",n.code=t.code||0,this.emit("error",n),this.inbound?this.destroy():this.reconnection?this.close():this.destroy()}close(){if(!this.destroyed){this.time=Date.now(),this.packet=null,this.handshake=!1,this.connected=!1,this.challenge=!1,this.sequence=0,this.lastPing=0;for(const[t,e]of this.jobs)this.jobs.delete(t),e.reject(new Error("Job timed out."));n(this.ws),this.ws.onopen=()=>{},this.ws.onmessage=()=>{},this.ws.onerror=()=>{},this.ws.onclose=()=>{},this.ws.close(),this.emitAsync("disconnect")}}error(t){this.destroyed||this.emit("error",new Error(t))}destroy(){this.destroyed||(this.close(),this.stop(),this.opened=!1,this.destroyed=!0,this.buffer.length=0,this.emitAsync("close"),this.removeAllListeners(),this.on("error",()=>{}))}send(t){this.destroyed||(n(this.ws),t.binary&&this.binary?this.ws.send(t.toRaw()):this.ws.send(t.toString()))}reconnect(){n(!this.inbound),this.close(),this.ws=new s(this.url),this.time=Date.now(),this.observe()}start(){n(this.ws),n(null==this.timer),this.timer=setInterval(()=>this.stall(),5e3)}stop(){null!=this.timer&&(clearInterval(this.timer),this.timer=null)}stall(){const t=Date.now();if(n(this.ws),!this.connected)return t-this.time>1e4?this.inbound||!this.reconnection?(this.error("Timed out waiting for connection."),void this.destroy()):(this.error("Timed out waiting for connection. Reconnecting..."),void this.reconnect()):void 0;for(const[e,r]of this.jobs)t-r.time>6e5&&(this.jobs.delete(e),r.reject(new Error("Job timed out.")));return this.inbound||this.challenge?!this.inbound&&t-this.lastPing>this.pingTimeout?(this.error("Connection is stalling (ping)."),this.inbound?void this.destroy():void this.close()):void 0:(this.challenge=!0,this.lastPing=t,void this.sendPing())}async handleFrame(t){if(!this.destroyed)switch(t.type){case a.types.OPEN:return this.handleOpen(t);case a.types.CLOSE:return this.handleClose(t);case a.types.PING:return this.handlePing(t);case a.types.PONG:return this.handlePong(t);case a.types.MESSAGE:return this.handleMessage(t);case a.types.UPGRADE:return this.handleUpgrade(t);case a.types.NOOP:return this.handleNoop(t);default:throw new Error("Unknown frame.")}}async handleOpen(t){if(this.inbound)throw new Error("Inbound socket sent an open frame.");if(t.binary)throw new Error("Received a binary open frame.");if(this.handshake)throw new Error("Duplicate open frame.");const e=JSON.parse(t.data);y(e&&"object"==typeof e,"open","object");const{pingInterval:r,pingTimeout:n}=e;y(r>>>0===r,"interval","uint32"),y(n>>>0===n,"timeout","uint32"),this.pingInterval=r,this.pingTimeout=n,this.handshake=!0,this.opened||(this.opened=!0,await this.emitAsync("open"))}async handleClose(t){if(this.inbound)throw new Error("Inbound socket sent a close frame.");this.close()}async handlePing(){if(!this.inbound)throw new Error("Outbound socket sent a ping frame.");this.sendPong()}async handlePong(){if(this.inbound)throw new Error("Inbound socket sent a pong frame.");if(!this.challenge)return this.error("Remote node sent bad pong."),void this.destroy();this.challenge=!1}async handleMessage(t){if(this.packet){const e=this.packet;if(!t.binary)throw new Error("Received non-binary frame as attachment.");return e.buffers.push(t.data),e.buffers.length===e.attachments?(this.packet=null,this.handlePacket(e)):void 0}if(t.binary)throw new Error("Received binary frame as a message.");const e=i.fromString(t.data);if(!(e.attachments>0))return this.handlePacket(e);this.packet=e}async handleUpgrade(t){if(!this.inbound)throw new Error("Outbound socket sent an upgrade frame.");throw new Error("Cannot upgrade from websocket.")}async handleNoop(t){}sendFrame(t,e,r){this.send(new a(t,e,r))}sendOpen(t){this.sendFrame(a.types.OPEN,t,!1)}sendClose(t){this.sendFrame(a.types.CLOSE,t,!1)}sendPing(t){this.sendFrame(a.types.PING,t,!1)}sendPong(t){this.sendFrame(a.types.PONG,t,!1)}sendMessage(t){this.sendFrame(a.types.MESSAGE,t,!1)}sendBinary(t){this.sendFrame(a.types.MESSAGE,t,!0)}sendHandshake(){const t=JSON.stringify({sid:"00000000000000000000",upgrades:[],pingInterval:this.pingInterval,pingTimeout:this.pingTimeout});this.sendOpen(t)}async handlePacket(t){if(!this.destroyed)switch(t.type){case i.types.CONNECT:return this.handleConnect();case i.types.DISCONNECT:return this.handleDisconnect();case i.types.EVENT:case i.types.BINARY_EVENT:{const e=t.getData();return y(Array.isArray(e),"args","array"),y(e.length>0,"args","array"),y("string"==typeof e[0],"event","string"),-1!==t.id?this.handleCall(t.id,e):this.handleEvent(e)}case i.types.ACK:case i.types.BINARY_ACK:{y(-1!==t.id,"id","uint32");const e=t.getData();y(null==e||Array.isArray(e),"args","array");let r=null,n=null;return e&&e.length>0&&(r=e[0]),e&&e.length>1&&(n=e[1]),null==n&&(n=null),r?(y("object"==typeof r,"error","object"),this.handleError(t.id,r)):this.handleAck(t.id,n)}case i.types.ERROR:{const e=t.getData();return y(e&&"object"==typeof e,"error","object"),this.handleError(-1,e)}default:throw new Error("Unknown packet.")}}async handleConnect(){if(this.inbound)throw new Error("Inbound socket sent connect packet.");this.connected=!0,await this.emitAsync("connect");for(const t of this.buffer)this.sendPacket(t);this.buffer.length=0}async handleDisconnect(){this.close()}async handleEvent(t){try{const e=t[0];if(f.hasOwnProperty(e))throw new Error(`Cannot emit blacklisted event: ${e}.`);this.events.emit(...t)}catch(t){this.emit("error",t),this.sendError(-1,t)}}async handleCall(t,e){let r;try{const t=e.shift();if(f.hasOwnProperty(t))throw new Error(`Cannot emit blacklisted event: ${t}.`);const n=this.hooks.get(t);if(!n)throw new Error(`Call not found: ${t}.`);r=await n(...e)}catch(e){return this.emit("error",e),void this.sendError(t,e)}null==r&&(r=null),this.sendAck(t,r)}async handleAck(t,e){const r=this.jobs.get(t);if(!r)throw new Error(`Job not found for ${t}.`);this.jobs.delete(t),r.resolve(e)}async handleError(t,e){const r=d(e.message),n=g(e.name),o=g(e.type),s=p(e.code);if(-1===t){const t=new Error(r);return t.name=n,t.type=o,t.code=s,void this.emit("error",t)}const i=this.jobs.get(t);if(!i)throw new Error(`Job not found for ${t}.`);this.jobs.delete(t);const a=new Error(r);a.name=n,a.type=o,a.code=s,i.reject(a)}sendPacket(t){this.sendMessage(t.toString());for(const e of t.buffers)this.sendBinary(e)}sendConnect(){this.sendPacket(new i(i.types.CONNECT))}sendDisconnect(){this.sendPacket(new i(i.types.DISCONNECT))}sendEvent(t){const e=new i;e.type=i.types.EVENT,e.setData(t),this.connected?this.sendPacket(e):this.buffer.push(e)}sendCall(t,e){const r=new i;r.type=i.types.EVENT,r.id=t,r.setData(e),this.connected?this.sendPacket(r):this.buffer.push(r)}sendAck(t,e){const r=new i;r.type=i.types.ACK,r.id=t,r.setData([null,e]),this.sendPacket(r)}sendError(t,e){const r=d(e.message),n=g(e.name),o=g(e.type),s=p(e.code);if(-1===t){const t=new i;return t.type=i.types.ERROR,t.setData({message:r,name:n,type:o,code:s}),void this.sendPacket(t)}const a=new i;a.type=i.types.ACK,a.id=t,a.setData([{message:r,name:n,type:o,code:s}]),this.sendPacket(a)}bind(t,e){y("string"==typeof t,"event","string"),y("function"==typeof e,"handler","function"),n(!f.hasOwnProperty(t),"Blacklisted event."),this.events.on(t,e)}unbind(t,e){y("string"==typeof t,"event","string"),y("function"==typeof e,"handler","function"),n(!f.hasOwnProperty(t),"Blacklisted event."),this.events.removeListener(t,e)}fire(...t){y(t.length>0,"event","string"),y("string"==typeof t[0],"event","string"),this.sendEvent(t)}hook(t,e){y("string"==typeof t,"event","string"),y("function"==typeof e,"handler","function"),n(!this.hooks.has(t),"Hook already bound."),n(!f.hasOwnProperty(t),"Blacklisted event."),this.hooks.set(t,e)}unhook(t){y("string"==typeof t,"event","string"),n(!f.hasOwnProperty(t),"Blacklisted event."),this.hooks.delete(t)}call(...t){y(t.length>0,"event","string"),y("string"==typeof t[0],"event","string");const e=this.sequence;return this.sequence+=1,this.sequence>>>=0,n(!this.jobs.has(e),"ID collision."),this.sendCall(e,t),new Promise((t,r)=>{this.jobs.set(e,new l(t,r,Date.now()))})}channel(t){return this.channels.has(t)}join(t){return!!this.server&&this.server.join(this,t)}leave(t){return!!this.server&&this.server.leave(this,t)}static accept(t,e,r,n){return(new this).accept(t,e,r,n)}static connect(t,e,r,n){return(new this).connect(t,e,r,n)}}}).call(this,r(1).Buffer)},function(t,e,r){"use strict";e.byteLength=function(t){var e=u(t),r=e[0],n=e[1];return 3*(r+n)/4-n},e.toByteArray=function(t){var e,r,n=u(t),i=n[0],a=n[1],h=new s(function(t,e,r){return 3*(e+r)/4-r}(0,i,a)),c=0,f=a>0?i-4:i;for(r=0;r>16&255,h[c++]=e>>8&255,h[c++]=255&e;2===a&&(e=o[t.charCodeAt(r)]<<2|o[t.charCodeAt(r+1)]>>4,h[c++]=255&e);1===a&&(e=o[t.charCodeAt(r)]<<10|o[t.charCodeAt(r+1)]<<4|o[t.charCodeAt(r+2)]>>2,h[c++]=e>>8&255,h[c++]=255&e);return h},e.fromByteArray=function(t){for(var e,r=t.length,o=r%3,s=[],i=0,a=r-o;ia?a:i+16383));1===o?(e=t[r-1],s.push(n[e>>2]+n[e<<4&63]+"==")):2===o&&(e=(t[r-2]<<8)+t[r-1],s.push(n[e>>10]+n[e>>4&63]+n[e<<2&63]+"="));return s.join("")};for(var n=[],o=[],s="undefined"!=typeof Uint8Array?Uint8Array:Array,i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",a=0,h=i.length;a0)throw new Error("Invalid string. Length must be a multiple of 4");var r=t.indexOf("=");return-1===r&&(r=e),[r,r===e?0:4-r%4]}function c(t,e,r){for(var o,s,i=[],a=e;a>18&63]+n[s>>12&63]+n[s>>6&63]+n[63&s]);return i.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},function(t,e){e.read=function(t,e,r,n,o){var s,i,a=8*o-n-1,h=(1<>1,c=-7,f=r?o-1:0,l=r?-1:1,p=t[e+f];for(f+=l,s=p&(1<<-c)-1,p>>=-c,c+=a;c>0;s=256*s+t[e+f],f+=l,c-=8);for(i=s&(1<<-c)-1,s>>=-c,c+=n;c>0;i=256*i+t[e+f],f+=l,c-=8);if(0===s)s=1-u;else{if(s===h)return i?NaN:1/0*(p?-1:1);i+=Math.pow(2,n),s-=u}return(p?-1:1)*i*Math.pow(2,s-n)},e.write=function(t,e,r,n,o,s){var i,a,h,u=8*s-o-1,c=(1<>1,l=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:s-1,d=n?1:-1,g=e<0||0===e&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(a=isNaN(e)?1:0,i=c):(i=Math.floor(Math.log(e)/Math.LN2),e*(h=Math.pow(2,-i))<1&&(i--,h*=2),(e+=i+f>=1?l/h:l*Math.pow(2,1-f))*h>=2&&(i++,h/=2),i+f>=c?(a=0,i=c):i+f>=1?(a=(e*h-1)*Math.pow(2,o),i+=f):(a=e*Math.pow(2,f-1)*Math.pow(2,o),i=0));o>=8;t[r+p]=255&a,p+=d,a/=256,o-=8);for(i=i<0;t[r+p]=255&i,p+=d,i/=256,u-=8);t[r+p-d]|=128*g}},function(t,e){var r={}.toString;t.exports=Array.isArray||function(t){return"[object Array]"==r.call(t)}},function(t,e,r){"use strict";(function(e){const n=r(0),o={CONNECT:0,DISCONNECT:1,EVENT:2,ACK:3,ERROR:4,BINARY_EVENT:5,BINARY_ACK:6};class s{constructor(t){this.type=t||0,this.attachments=0,this.nsp="/",this.id=-1,this.data="",this.buffers=[]}setData(t){n(void 0!==t),n("number"!=typeof t),n("function"!=typeof t);const[r,s]=function(t){const r=[],n=function t(r,n,o,s){if(null===n||"object"!=typeof n)return n;if(e.isBuffer(n)){const t=s.get(n);if(null!=t)return t;const e={_placeholder:!0,num:o.length};return s.set(n,e),o.push(n),e}if(s.has(n))throw new TypeError("Converting circular structure to JSON.");if(Array.isArray(n)){const e=[];s.set(n,null);for(let r=0;r0)switch(this.type){case o.EVENT:this.type=o.BINARY_EVENT;break;case o.ACK:this.type=o.BINARY_ACK}return this}getData(){return 0===this.data.length?null:(t=this.data,e=this.buffers,JSON.parse(t,(t,r)=>(function(t){return null!==t&&"object"==typeof t&&!0===t._placeholder&&t.num>>>0===t.num})(r)&&r.num0);let e=0,r=0,s=0,a="/",h=-1,u="";switch([e,r]=function(t,e){const r=t.charCodeAt(e)-48;return r<0||r>9?-1:[e+1,r]}(t,e),n(-1!==r),n(r<=o.BINARY_ACK),r){case o.BINARY_EVENT:case o.BINARY_ACK:[e,s]=i(t,e),n(-1!==s),n(e9)break;o*=10,o+=s,n((r+=1)<=10)}return n(o<=4294967295),0===r&&(o=-1),[e,o]}s.types=o,t.exports=s}).call(this,r(1).Buffer)},function(t,e,r){"use strict";const n=r(0),o=r(15);e.parseURL=function(t){-1===t.indexOf("://")&&(t=`ws://${t}`);const e=o.parse(t);if("http:"!==e.protocol&&"https:"!==e.protocol&&"ws:"!==e.protocol&&"wss:"!==e.protocol)throw new Error("Invalid protocol for websocket URL.");if(!e.hostname)throw new Error("Malformed URL.");const r=e.hostname;let s=80,i=!1;return"https:"!==e.protocol&&"wss:"!==e.protocol||(s=443,i=!0),e.port&&(s=parseInt(e.port,10),n((65535&s)===s),n(0!==s)),[s,r,i]}},function(t,e,r){"use strict";var n=r(16),o=r(18);function s(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}e.parse=v,e.resolve=function(t,e){return v(t,!1,!0).resolve(e)},e.resolveObject=function(t,e){return t?v(t,!1,!0).resolveObject(e):e},e.format=function(t){o.isString(t)&&(t=v(t));return t instanceof s?t.format():s.prototype.format.call(t)},e.Url=s;var i=/^([a-z0-9.+-]+:)/i,a=/:[0-9]*$/,h=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,u=["{","}","|","\\","^","`"].concat(["<",">",'"',"`"," ","\r","\n","\t"]),c=["'"].concat(u),f=["%","/","?",";","#"].concat(c),l=["/","?","#"],p=/^[+a-z0-9A-Z_-]{0,63}$/,d=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,g={javascript:!0,"javascript:":!0},y={javascript:!0,"javascript:":!0},m={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},w=r(19);function v(t,e,r){if(t&&o.isObject(t)&&t instanceof s)return t;var n=new s;return n.parse(t,e,r),n}s.prototype.parse=function(t,e,r){if(!o.isString(t))throw new TypeError("Parameter 'url' must be a string, not "+typeof t);var s=t.indexOf("?"),a=-1!==s&&s127?N+="x":N+=x[I];if(!N.match(p)){var U=j.slice(0,P),L=j.slice(P+1),M=x.match(d);M&&(U.push(M[1]),L.unshift(M[2])),L.length&&(v="/"+L.join(".")+v),this.hostname=U.join(".");break}}}this.hostname.length>255?this.hostname="":this.hostname=this.hostname.toLowerCase(),T||(this.hostname=n.toASCII(this.hostname));var D=this.port?":"+this.port:"",Y=this.hostname||"";this.host=Y+D,this.href+=this.host,T&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==v[0]&&(v="/"+v))}if(!g[A])for(P=0,C=c.length;P0)&&r.host.split("@"))&&(r.auth=T.shift(),r.host=r.hostname=T.shift());return r.search=t.search,r.query=t.query,o.isNull(r.pathname)&&o.isNull(r.search)||(r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")),r.href=r.format(),r}if(!O.length)return r.pathname=null,r.search?r.path="/"+r.search:r.path=null,r.href=r.format(),r;for(var R=O.slice(-1)[0],_=(r.host||t.host||O.length>1)&&("."===R||".."===R)||""===R,P=0,k=O.length;k>=0;k--)"."===(R=O[k])?O.splice(k,1):".."===R?(O.splice(k,1),P++):P&&(O.splice(k,1),P--);if(!E&&!A)for(;P--;P)O.unshift("..");!E||""===O[0]||O[0]&&"/"===O[0].charAt(0)||O.unshift(""),_&&"/"!==O.join("/").substr(-1)&&O.push("");var T,j=""===O[0]||O[0]&&"/"===O[0].charAt(0);S&&(r.hostname=r.host=j?"":O.length?O.shift():"",(T=!!(r.host&&r.host.indexOf("@")>0)&&r.host.split("@"))&&(r.auth=T.shift(),r.host=r.hostname=T.shift()));return(E=E||r.host&&O.length)&&!j&&O.unshift(""),O.length?r.pathname=O.join("/"):(r.pathname=null,r.path=null),o.isNull(r.pathname)&&o.isNull(r.search)||(r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")),r.auth=t.auth||r.auth,r.slashes=r.slashes||t.slashes,r.href=r.format(),r},s.prototype.parseHost=function(){var t=this.host,e=a.exec(t);e&&(":"!==(e=e[0])&&(this.port=e.substr(1)),t=t.substr(0,t.length-e.length)),t&&(this.hostname=t)}},function(t,e,r){(function(t,n){var o;/*! https://mths.be/punycode v1.4.1 by @mathias */!function(s){e&&e.nodeType,t&&t.nodeType;var i="object"==typeof n&&n;i.global!==i&&i.window!==i&&i.self;var a,h=2147483647,u=36,c=1,f=26,l=38,p=700,d=72,g=128,y="-",m=/^xn--/,w=/[^\x20-\x7E]/,v=/[\x2E\u3002\uFF0E\uFF61]/g,b={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},E=u-c,A=Math.floor,O=String.fromCharCode;function S(t){throw new RangeError(b[t])}function R(t,e){for(var r=t.length,n=[];r--;)n[r]=e(t[r]);return n}function _(t,e){var r=t.split("@"),n="";return r.length>1&&(n=r[0]+"@",t=r[1]),n+R((t=t.replace(v,".")).split("."),e).join(".")}function P(t){for(var e,r,n=[],o=0,s=t.length;o=55296&&e<=56319&&o65535&&(e+=O((t-=65536)>>>10&1023|55296),t=56320|1023&t),e+=O(t)})).join("")}function T(t,e){return t+22+75*(t<26)-((0!=e)<<5)}function j(t,e,r){var n=0;for(t=r?A(t/p):t>>1,t+=A(t/e);t>E*f>>1;n+=u)t=A(t/E);return A(n+(E+1)*t/(t+l))}function C(t){var e,r,n,o,s,i,a,l,p,m,w,v=[],b=t.length,E=0,O=g,R=d;for((r=t.lastIndexOf(y))<0&&(r=0),n=0;n=128&&S("not-basic"),v.push(t.charCodeAt(n));for(o=r>0?r+1:0;o=b&&S("invalid-input"),((l=(w=t.charCodeAt(o++))-48<10?w-22:w-65<26?w-65:w-97<26?w-97:u)>=u||l>A((h-E)/i))&&S("overflow"),E+=l*i,!(l<(p=a<=R?c:a>=R+f?f:a-R));a+=u)i>A(h/(m=u-p))&&S("overflow"),i*=m;R=j(E-s,e=v.length+1,0==s),A(E/e)>h-O&&S("overflow"),O+=A(E/e),E%=e,v.splice(E++,0,O)}return k(v)}function x(t){var e,r,n,o,s,i,a,l,p,m,w,v,b,E,R,_=[];for(v=(t=P(t)).length,e=g,r=0,s=d,i=0;i=e&&wA((h-r)/(b=n+1))&&S("overflow"),r+=(a-e)*b,e=a,i=0;ih&&S("overflow"),w==e){for(l=r,p=u;!(l<(m=p<=s?c:p>=s+f?f:p-s));p+=u)R=l-m,E=u-m,_.push(O(T(m+R%E,0))),l=A(R/E);_.push(O(T(l,0))),s=j(r,b,n==o),r=0,++n}++r,++e}return _.join("")}a={version:"1.4.1",ucs2:{decode:P,encode:k},decode:C,encode:x,toASCII:function(t){return _(t,(function(t){return w.test(t)?"xn--"+x(t):t}))},toUnicode:function(t){return _(t,(function(t){return m.test(t)?C(t.slice(4).toLowerCase()):t}))}},void 0===(o=function(){return a}.call(e,r,e,t))||(t.exports=o)}()}).call(this,r(17)(t),r(2))},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children||(t.children=[]),Object.defineProperty(t,"loaded",{enumerable:!0,get:function(){return t.l}}),Object.defineProperty(t,"id",{enumerable:!0,get:function(){return t.i}}),t.webpackPolyfill=1),t}},function(t,e,r){"use strict";t.exports={isString:function(t){return"string"==typeof t},isObject:function(t){return"object"==typeof t&&null!==t},isNull:function(t){return null===t},isNullOrUndefined:function(t){return null==t}}},function(t,e,r){"use strict";e.decode=e.parse=r(20),e.encode=e.stringify=r(21)},function(t,e,r){"use strict";function n(t,e){return Object.prototype.hasOwnProperty.call(t,e)}t.exports=function(t,e,r,s){e=e||"&",r=r||"=";var i={};if("string"!=typeof t||0===t.length)return i;var a=/\+/g;t=t.split(e);var h=1e3;s&&"number"==typeof s.maxKeys&&(h=s.maxKeys);var u=t.length;h>0&&u>h&&(u=h);for(var c=0;c=0?(f=g.substr(0,y),l=g.substr(y+1)):(f=g,l=""),p=decodeURIComponent(f),d=decodeURIComponent(l),n(i,p)?o(i[p])?i[p].push(d):i[p]=[i[p],d]:i[p]=d}return i};var o=Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)}},function(t,e,r){"use strict";var n=function(t){switch(typeof t){case"string":return t;case"boolean":return t?"true":"false";case"number":return isFinite(t)?t:"";default:return""}};t.exports=function(t,e,r,a){return e=e||"&",r=r||"=",null===t&&(t=void 0),"object"==typeof t?s(i(t),(function(i){var a=encodeURIComponent(n(i))+r;return o(t[i])?s(t[i],(function(t){return a+encodeURIComponent(n(t))})).join(e):a+encodeURIComponent(n(t[i]))})).join(e):a?encodeURIComponent(n(a))+r+encodeURIComponent(n(t)):""};var o=Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)};function s(t,e){if(t.map)return t.map(e);for(var r=[],n=0;ni)return void this.error("Frame too large.");let r;try{r=s.fromRaw(t)}catch(t){return void this.emit("error",t)}this.emit("frame",r)}feedString(t){if(n("string"==typeof t),e.byteLength(t,"utf8")>i)return void this.error("Frame too large.");let r;try{r=s.fromString(t)}catch(t){return void this.emit("error",t)}this.emit("frame",r)}}}).call(this,r(1).Buffer)},function(t,e,r){"use strict";t.exports={1e3:"NORMAL_CLOSURE",1001:"GOING_AWAY",1002:"PROTOCOL_ERROR",1003:"UNSUPPORTED_DATA",1004:"RESERVED",1005:"NO_STATUS_RECVD",1006:"ABNORMAL_CLOSURE",1007:"INVALID_FRAME_PAYLOAD_DATA",1008:"POLICY_VIOLATION",1009:"MESSAGE_TOO_BIG",1010:"MISSING_EXTENSION",1011:"INTERNAL_ERROR",1012:"SERVICE_RESTART",1013:"TRY_AGAIN_LATER",1014:"BAD_GATEWAY",1015:"TLS_HANDSHAKE"}},function(t,e,r){"use strict";t.exports={connect:!0,connect_error:!0,connect_timeout:!0,connecting:!0,disconnect:!0,error:!0,reconnect:!0,reconnect_attempt:!0,reconnect_failed:!0,reconnect_error:!0,reconnecting:!0,ping:!0,pong:!0}}])); \ No newline at end of file diff --git a/lib/src/backend/RPCSocketServer.d.ts b/lib/src/backend/RPCSocketServer.d.ts new file mode 100644 index 0000000..55c5836 --- /dev/null +++ b/lib/src/backend/RPCSocketServer.d.ts @@ -0,0 +1,96 @@ +import { Socket } from "./RPCSocketServer"; +declare type rpcType = 'hook' | 'unhook' | 'call'; +declare type visibility = 'public' | 'private'; +export declare type Outcome = "Success" | "Error"; +export declare class Response { + message?: string | undefined; + constructor(message?: string | undefined); +} +export declare class SuccessResponse extends Response { + result: Outcome; + constructor(message?: string); +} +export declare class ErrorResponse extends Response { + result: Outcome; + constructor(message?: string); +} +export declare class SubscriptionResponse extends SuccessResponse { + uid: string; + constructor(uid: string, message?: string); +} +export declare type UnhookFunction = (uid: string) => Promise; +export declare type callbackFunction = (...args: any[]) => Promise; +export declare type AsyncFunction = (...args: any[]) => Promise; +export interface RPCExporter { + name: string; + exportRPCs(): socketioRPC[]; +} +declare type baseRPC = { + type: rpcType; + name: string; + visibility: visibility; +}; +declare type hookRPC = baseRPC & { + type: 'hook'; + func: callbackFunction; + unhook: UnhookFunction; +}; +declare type unhookRPC = baseRPC & { + type: 'unhook'; + func: UnhookFunction; +}; +declare type callRPC = baseRPC & { + type: 'call'; + func: (...args: any[]) => Promise; +}; +export declare type socketioRPC = callRPC | unhookRPC | hookRPC; +export declare type baseInfo = { + owner: string; + argNames: string[]; +}; +declare type HookInfo = baseRPC & baseInfo & { + type: 'hook'; + generator: (socket: any) => callbackFunction; + unhook: UnhookFunction; +}; +declare type UnhookInfo = baseRPC & baseInfo & { + type: 'unhook'; + func: UnhookFunction; +}; +declare type CallInfo = baseRPC & baseInfo & { + type: 'call'; + func: AsyncFunction; +}; +declare type RpcInfo = HookInfo | UnhookInfo | CallInfo; +export declare type ExtendedRpcInfo = RpcInfo & { + uniqueName: string; +}; +export declare const rpcToRpcinfo: (rpc: socketioRPC, owner: string) => RpcInfo; +export declare const rpcHooker: (socket: Socket, owner: string, RPCs: socketioRPC[], makeUnique?: boolean) => ExtendedRpcInfo[]; +declare type OnFunction = (type: 'error' | 'close', f: (e?: any) => void) => Socket; +export declare type Socket = { + port: number; + hook: (rpcname: string, ...args: any[]) => Socket; + unhook: (rpcname: string) => Socket; + call: (rpcname: string, ...args: any[]) => Promise; + fire: (rpcname: string, ...args: any[]) => Promise; + on: OnFunction; + destroy: () => void; + close: () => void; +}; +export declare type RPCSocketConf = { + connectionHandler: (socket: Socket) => void; + errorHandler: (socket: Socket) => (error: any) => void; + closeHandler: (socket: Socket) => () => void; +}; +export declare class RPCSocketServer { + private port; + private rpcExporters; + private conf; + private io; + private wsServer; + constructor(port: number, rpcExporters?: RPCExporter[], conf?: RPCSocketConf); + private startWebsocket; + protected initApis(socket: any): void; +} +export {}; diff --git a/lib/src/backend/RPCSocketServer.js b/lib/src/backend/RPCSocketServer.js new file mode 100644 index 0000000..e8977c5 --- /dev/null +++ b/lib/src/backend/RPCSocketServer.js @@ -0,0 +1,152 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const http = require("http"); +const bsock = require("bsock"); +const uuid = require("uuid/v4"); +/* Responses */ +class Response { + constructor(message) { + this.message = message; + } +} +exports.Response = Response; +class SuccessResponse extends Response { + constructor(message) { + super(message); + this.result = "Success"; + } +} +exports.SuccessResponse = SuccessResponse; +class ErrorResponse extends Response { + constructor(message = "Unknown error") { + super(message); + this.result = "Error"; + } +} +exports.ErrorResponse = ErrorResponse; +class SubscriptionResponse extends SuccessResponse { + constructor(uid, message) { + super(message); + this.uid = uid; + } +} +exports.SubscriptionResponse = SubscriptionResponse; +exports.rpcToRpcinfo = (rpc, owner) => { + switch (rpc.type) { + case "call": + return { + owner: owner, + argNames: extractArgs(rpc.func), + type: rpc.type, + visibility: rpc.visibility, + name: rpc.name, + func: rpc.func, + }; + case "unhook": + return { + owner: owner, + argNames: extractArgs(rpc.func), + type: rpc.type, + visibility: rpc.visibility, + name: rpc.name, + func: rpc.func, + }; + case "hook": + const generator = hookGenerator(rpc); + return { + owner: owner, + argNames: extractArgs(generator(undefined)), + type: rpc.type, + visibility: rpc.visibility, + name: rpc.name, + unhook: rpc.unhook, + generator: generator, + }; + } +}; +exports.rpcHooker = (socket, owner, RPCs, makeUnique = true) => { + const suffix = makeUnique ? "-" + uuid().substr(0, 4) : ""; + return RPCs.map(rpc => exports.rpcToRpcinfo(rpc, owner)) + .map(info => { + const ret = info; + ret.uniqueName = info.name + suffix; + switch (info.type) { + case "hook": + socket.hook(ret.uniqueName, info.generator(socket)); + break; + default: + socket.hook(ret.uniqueName, info.func); + } + socket.on('close', () => socket.unhook(info.name)); + return ret; + }); +}; +const hookGenerator = (rpc) => { + const argsArr = extractArgs(rpc.func); + argsArr.pop(); + const args = argsArr.join(','); + return eval(`(socket) => async (` + args + `) => { + const res = await rpc.func(` + args + (args.length !== 0 ? ',' : '') + ` (x) => { + socket.call(res.uid, x) + }) + if(res.result == 'Success'){ + socket.on('close', async () => { + const unhookRes = await rpc.unhook(res.uid) + console.log("Specific close handler for", rpc.name, res.uid, unhookRes) + }) + + } + return res + }`); +}; +const extractArgs = (f) => { + let fn = String(f); + let args = fn.substr(0, fn.indexOf(")")); + args = args.substr(fn.indexOf("(") + 1); + let ret = args.split(","); + return ret; +}; +class RPCSocketServer { + constructor(port, rpcExporters = [], conf = { + errorHandler: (socket) => (error) => { socket.destroy(); console.error(error); }, + closeHandler: (socket) => () => { console.log("Socket closing"); }, + connectionHandler: (socket) => { console.log("New websocket connection in port " + socket.port); } + }) { + this.port = port; + this.rpcExporters = rpcExporters; + this.conf = conf; + this.io = bsock.createServer(); + this.wsServer = http.createServer(); + this.startWebsocket(); + } + startWebsocket() { + try { + this.io.attach(this.wsServer); + this.io.on('socket', (socket) => { + socket.on('error', this.conf.errorHandler(socket)); + socket.on('close', this.conf.closeHandler(socket)); + this.initApis(socket); + }); + this.wsServer.listen(this.port); + } + catch (e) { + //@ts-ignore + this.errorHandler(undefined)("Unable to connect to socket"); + } + } + initApis(socket) { + const adminRPCs = [ + { + name: 'info', + type: 'call', + visibility: 'private', + func: async () => rpcInfos + } + ]; + const rpcInfos = [ + ...exports.rpcHooker(socket, "Admin", adminRPCs, false), + ...this.rpcExporters.flatMap(exporter => exports.rpcHooker(socket, exporter.name, exporter.exportRPCs())) + ]; + } +} +exports.RPCSocketServer = RPCSocketServer; diff --git a/lib/src/frontend/RPCaller.d.ts b/lib/src/frontend/RPCaller.d.ts new file mode 100644 index 0000000..b4f2ecc --- /dev/null +++ b/lib/src/frontend/RPCaller.d.ts @@ -0,0 +1,20 @@ +declare type RPCReceiver = { + [RPCGroup in string]: any; +}; +/** + * Dynamic library to communicate with FrontblockService remotely + * + * This will be automatically injected into the webpages served by FrontblockService + * Will ask it's service for available RPCs and parse them into methods of this object + * for convenient access. + */ +export declare class RPCaller implements RPCReceiver { + private socket; + constructor(port: number, server: string, tls?: boolean); + connect(): Promise; + info(): Promise; + private callGenerator; + private hookGenerator; + private unhookGenerator; +} +export {}; diff --git a/lib/src/frontend/RPCaller.js b/lib/src/frontend/RPCaller.js new file mode 100644 index 0000000..06f929c --- /dev/null +++ b/lib/src/frontend/RPCaller.js @@ -0,0 +1,71 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var bsock = require('bsock'); +//fix args with defaults like "force = true" -> "force" +function stripAfterEquals(str) { + return str.split("=")[0]; +} +/** + * Dynamic library to communicate with FrontblockService remotely + * + * This will be automatically injected into the webpages served by FrontblockService + * Will ask it's service for available RPCs and parse them into methods of this object + * for convenient access. + */ +class RPCaller { + constructor(port, server, tls = false) { + this.socket = bsock.connect(port, server, tls); + } + async connect() { + const info = await this.info(); + info.forEach(i => { + let f; + switch (i.type) { + case 'call': + f = this.callGenerator(i.uniqueName, i.argNames); + break; + case 'hook': + f = this.hookGenerator(i.uniqueName, i.argNames); + break; + case 'unhook': + f = this.unhookGenerator(i.uniqueName, i.argNames); + break; + } + if (this[i.owner] == null) + this[i.owner] = {}; + this[i.owner][i.name] = f; + this[i.owner][i.name].bind(this); + }); + } + async info() { + return await this.socket.call('info'); + } + callGenerator(fnName, fnArgs) { + const headerArgs = fnArgs.join(","); + const argParams = fnArgs.map(stripAfterEquals).join(","); + return eval('( () => async (' + headerArgs + ') => { return await this.socket.call("' + fnName + '", ' + argParams + ')} )()'); + } + hookGenerator(fnName, fnArgs) { + const headerArgs = fnArgs.join(","); + const argParams = fnArgs.map(stripAfterEquals).join(","); + return eval(`( () => async (` + headerArgs + (headerArgs.length !== 0 ? "," : "") + ` callback) => { + const r = await this.socket.call("` + fnName + `", ` + argParams + `) + if(r.uid != null){ + this.socket.hook(res.uid, callback) + } + return res + } )()`); + } + unhookGenerator(fnName, fnArgs) { + const headerArgs = fnArgs.join(","); + const argParams = fnArgs.map(stripAfterEquals).join(","); + if (fnArgs.length != 1) + console.error("UnhookFunction", fnName, "specified more than one argument: (" + headerArgs + ")"); + return eval(`( () => async (` + headerArgs + `) => { + const r = await this.socket.call("` + fnName + `", ` + argParams + `) + this.socket.unhook(` + argParams + `) + return res + } )()`); + } +} +exports.RPCaller = RPCaller; diff --git a/lib/test/test.d.ts b/lib/test/test.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/lib/test/test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/lib/test/test.js b/lib/test/test.js new file mode 100644 index 0000000..f4cf0df --- /dev/null +++ b/lib/test/test.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const RPCSocketServer_1 = require("../src/backend/RPCSocketServer"); +//@ts-ignore +const RPCaller_1 = require("../src/frontend/RPCaller"); +new RPCSocketServer_1.RPCSocketServer(20000, [{ + name: "HelloWorldRPCGroup", + exportRPCs: () => [{ + type: 'call', + name: 'echo', + func: async (s) => s, + visibility: 'private' + }] + }]); +const caller = new RPCaller_1.RPCaller(20000, 'localhost'); +caller.connect().then(_ => { + caller.info().then(console.log); + caller["HelloWorldRPCGroup"].echo("x").then(console.log); +}); diff --git a/node_modules/.bin/uuid b/node_modules/.bin/uuid new file mode 120000 index 0000000..b3e45bc --- /dev/null +++ b/node_modules/.bin/uuid @@ -0,0 +1 @@ +../uuid/bin/uuid \ No newline at end of file diff --git a/node_modules/uuid/AUTHORS b/node_modules/uuid/AUTHORS new file mode 100644 index 0000000..5a10523 --- /dev/null +++ b/node_modules/uuid/AUTHORS @@ -0,0 +1,5 @@ +Robert Kieffer +Christoph Tavan +AJ ONeal +Vincent Voyer +Roman Shtylman diff --git a/node_modules/uuid/CHANGELOG.md b/node_modules/uuid/CHANGELOG.md new file mode 100644 index 0000000..1ff6978 --- /dev/null +++ b/node_modules/uuid/CHANGELOG.md @@ -0,0 +1,112 @@ +# Changelog + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +### [3.3.3](https://github.com/kelektiv/node-uuid/compare/v3.3.2...v3.3.3) (2019-08-19) + + +## [3.3.2](https://github.com/kelektiv/node-uuid/compare/v3.3.1...v3.3.2) (2018-06-28) + + +### Bug Fixes + +* typo ([305d877](https://github.com/kelektiv/node-uuid/commit/305d877)) + + + + +## [3.3.1](https://github.com/kelektiv/node-uuid/compare/v3.3.0...v3.3.1) (2018-06-28) + + +### Bug Fixes + +* fix [#284](https://github.com/kelektiv/node-uuid/issues/284) by setting function name in try-catch ([f2a60f2](https://github.com/kelektiv/node-uuid/commit/f2a60f2)) + + + + +# [3.3.0](https://github.com/kelektiv/node-uuid/compare/v3.2.1...v3.3.0) (2018-06-22) + + +### Bug Fixes + +* assignment to readonly property to allow running in strict mode ([#270](https://github.com/kelektiv/node-uuid/issues/270)) ([d062fdc](https://github.com/kelektiv/node-uuid/commit/d062fdc)) +* fix [#229](https://github.com/kelektiv/node-uuid/issues/229) ([c9684d4](https://github.com/kelektiv/node-uuid/commit/c9684d4)) +* Get correct version of IE11 crypto ([#274](https://github.com/kelektiv/node-uuid/issues/274)) ([153d331](https://github.com/kelektiv/node-uuid/commit/153d331)) +* mem issue when generating uuid ([#267](https://github.com/kelektiv/node-uuid/issues/267)) ([c47702c](https://github.com/kelektiv/node-uuid/commit/c47702c)) + +### Features + +* enforce Conventional Commit style commit messages ([#282](https://github.com/kelektiv/node-uuid/issues/282)) ([cc9a182](https://github.com/kelektiv/node-uuid/commit/cc9a182)) + + + +## [3.2.1](https://github.com/kelektiv/node-uuid/compare/v3.2.0...v3.2.1) (2018-01-16) + + +### Bug Fixes + +* use msCrypto if available. Fixes [#241](https://github.com/kelektiv/node-uuid/issues/241) ([#247](https://github.com/kelektiv/node-uuid/issues/247)) ([1fef18b](https://github.com/kelektiv/node-uuid/commit/1fef18b)) + + + + +# [3.2.0](https://github.com/kelektiv/node-uuid/compare/v3.1.0...v3.2.0) (2018-01-16) + + +### Bug Fixes + +* remove mistakenly added typescript dependency, rollback version (standard-version will auto-increment) ([09fa824](https://github.com/kelektiv/node-uuid/commit/09fa824)) +* use msCrypto if available. Fixes [#241](https://github.com/kelektiv/node-uuid/issues/241) ([#247](https://github.com/kelektiv/node-uuid/issues/247)) ([1fef18b](https://github.com/kelektiv/node-uuid/commit/1fef18b)) + + +### Features + +* Add v3 Support ([#217](https://github.com/kelektiv/node-uuid/issues/217)) ([d94f726](https://github.com/kelektiv/node-uuid/commit/d94f726)) + + +# [3.1.0](https://github.com/kelektiv/node-uuid/compare/v3.1.0...v3.0.1) (2017-06-17) + +### Bug Fixes + +* (fix) Add .npmignore file to exclude test/ and other non-essential files from packing. (#183) +* Fix typo (#178) +* Simple typo fix (#165) + +### Features +* v5 support in CLI (#197) +* V5 support (#188) + + +# 3.0.1 (2016-11-28) + +* split uuid versions into separate files + + +# 3.0.0 (2016-11-17) + +* remove .parse and .unparse + + +# 2.0.0 + +* Removed uuid.BufferClass + + +# 1.4.0 + +* Improved module context detection +* Removed public RNG functions + + +# 1.3.2 + +* Improve tests and handling of v1() options (Issue #24) +* Expose RNG option to allow for perf testing with different generators + + +# 1.3.0 + +* Support for version 1 ids, thanks to [@ctavan](https://github.com/ctavan)! +* Support for node.js crypto API +* De-emphasizing performance in favor of a) cryptographic quality PRNGs where available and b) more manageable code diff --git a/node_modules/uuid/LICENSE.md b/node_modules/uuid/LICENSE.md new file mode 100644 index 0000000..8c84e39 --- /dev/null +++ b/node_modules/uuid/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2010-2016 Robert Kieffer and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/uuid/README.md b/node_modules/uuid/README.md new file mode 100644 index 0000000..6fc3708 --- /dev/null +++ b/node_modules/uuid/README.md @@ -0,0 +1,293 @@ + + +# uuid [![Build Status](https://secure.travis-ci.org/kelektiv/node-uuid.svg?branch=master)](http://travis-ci.org/kelektiv/node-uuid) # + +Simple, fast generation of [RFC4122](http://www.ietf.org/rfc/rfc4122.txt) UUIDS. + +Features: + +* Support for version 1, 3, 4 and 5 UUIDs +* Cross-platform +* Uses cryptographically-strong random number APIs (when available) +* Zero-dependency, small footprint (... but not [this small](https://gist.github.com/982883)) + +[**Deprecation warning**: The use of `require('uuid')` is deprecated and will not be +supported after version 3.x of this module. Instead, use `require('uuid/[v1|v3|v4|v5]')` as shown in the examples below.] + +## Quickstart - CommonJS (Recommended) + +```shell +npm install uuid +``` + +Then generate your uuid version of choice ... + +Version 1 (timestamp): + +```javascript +const uuidv1 = require('uuid/v1'); +uuidv1(); // ⇨ '2c5ea4c0-4067-11e9-8bad-9b1deb4d3b7d' + +``` + +Version 3 (namespace): + +```javascript +const uuidv3 = require('uuid/v3'); + +// ... using predefined DNS namespace (for domain names) +uuidv3('hello.example.com', uuidv3.DNS); // ⇨ '9125a8dc-52ee-365b-a5aa-81b0b3681cf6' + +// ... using predefined URL namespace (for, well, URLs) +uuidv3('http://example.com/hello', uuidv3.URL); // ⇨ 'c6235813-3ba4-3801-ae84-e0a6ebb7d138' + +// ... using a custom namespace +// +// Note: Custom namespaces should be a UUID string specific to your application! +// E.g. the one here was generated using this modules `uuid` CLI. +const MY_NAMESPACE = '1b671a64-40d5-491e-99b0-da01ff1f3341'; +uuidv3('Hello, World!', MY_NAMESPACE); // ⇨ 'e8b5a51d-11c8-3310-a6ab-367563f20686' + +``` + +Version 4 (random): + +```javascript +const uuidv4 = require('uuid/v4'); +uuidv4(); // ⇨ '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed' + +``` + +Version 5 (namespace): + +```javascript +const uuidv5 = require('uuid/v5'); + +// ... using predefined DNS namespace (for domain names) +uuidv5('hello.example.com', uuidv5.DNS); // ⇨ 'fdda765f-fc57-5604-a269-52a7df8164ec' + +// ... using predefined URL namespace (for, well, URLs) +uuidv5('http://example.com/hello', uuidv5.URL); // ⇨ '3bbcee75-cecc-5b56-8031-b6641c1ed1f1' + +// ... using a custom namespace +// +// Note: Custom namespaces should be a UUID string specific to your application! +// E.g. the one here was generated using this modules `uuid` CLI. +const MY_NAMESPACE = '1b671a64-40d5-491e-99b0-da01ff1f3341'; +uuidv5('Hello, World!', MY_NAMESPACE); // ⇨ '630eb68f-e0fa-5ecc-887a-7c7a62614681' + +``` + +## Quickstart - Browser-ready Versions + +Browser-ready versions of this module are available via [wzrd.in](https://github.com/jfhbrook/wzrd.in). + +For version 1 uuids: + +```html + + +``` + +For version 3 uuids: + +```html + + +``` + +For version 4 uuids: + +```html + + +``` + +For version 5 uuids: + +```html + + +``` + +## API + +### Version 1 + +```javascript +const uuidv1 = require('uuid/v1'); + +// Incantations +uuidv1(); +uuidv1(options); +uuidv1(options, buffer, offset); +``` + +Generate and return a RFC4122 v1 (timestamp-based) UUID. + +* `options` - (Object) Optional uuid state to apply. Properties may include: + + * `node` - (Array) Node id as Array of 6 bytes (per 4.1.6). Default: Randomly generated ID. See note 1. + * `clockseq` - (Number between 0 - 0x3fff) RFC clock sequence. Default: An internally maintained clockseq is used. + * `msecs` - (Number) Time in milliseconds since unix Epoch. Default: The current time is used. + * `nsecs` - (Number between 0-9999) additional time, in 100-nanosecond units. Ignored if `msecs` is unspecified. Default: internal uuid counter is used, as per 4.2.1.2. + +* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written. +* `offset` - (Number) Starting index in `buffer` at which to begin writing. + +Returns `buffer`, if specified, otherwise the string form of the UUID + +Note: The default [node id](https://tools.ietf.org/html/rfc4122#section-4.1.6) (the last 12 digits in the UUID) is generated once, randomly, on process startup, and then remains unchanged for the duration of the process. + +Example: Generate string UUID with fully-specified options + +```javascript +const v1options = { + node: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab], + clockseq: 0x1234, + msecs: new Date('2011-11-01').getTime(), + nsecs: 5678 +}; +uuidv1(v1options); // ⇨ '710b962e-041c-11e1-9234-0123456789ab' + +``` + +Example: In-place generation of two binary IDs + +```javascript +// Generate two ids in an array +const arr = new Array(); +uuidv1(null, arr, 0); // ⇨ [ 44, 94, 164, 192, 64, 103, 17, 233, 146, 52, 155, 29, 235, 77, 59, 125 ] +uuidv1(null, arr, 16); // ⇨ [ 44, 94, 164, 192, 64, 103, 17, 233, 146, 52, 155, 29, 235, 77, 59, 125, 44, 94, 164, 193, 64, 103, 17, 233, 146, 52, 155, 29, 235, 77, 59, 125 ] + +``` + +### Version 3 + +```javascript +const uuidv3 = require('uuid/v3'); + +// Incantations +uuidv3(name, namespace); +uuidv3(name, namespace, buffer); +uuidv3(name, namespace, buffer, offset); +``` + +Generate and return a RFC4122 v3 UUID. + +* `name` - (String | Array[]) "name" to create UUID with +* `namespace` - (String | Array[]) "namespace" UUID either as a String or Array[16] of byte values +* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written. +* `offset` - (Number) Starting index in `buffer` at which to begin writing. Default = 0 + +Returns `buffer`, if specified, otherwise the string form of the UUID + +Example: + +```javascript +uuidv3('hello world', MY_NAMESPACE); // ⇨ '042ffd34-d989-321c-ad06-f60826172424' + +``` + +### Version 4 + +```javascript +const uuidv4 = require('uuid/v4') + +// Incantations +uuidv4(); +uuidv4(options); +uuidv4(options, buffer, offset); +``` + +Generate and return a RFC4122 v4 UUID. + +* `options` - (Object) Optional uuid state to apply. Properties may include: + * `random` - (Number[16]) Array of 16 numbers (0-255) to use in place of randomly generated values + * `rng` - (Function) Random # generator function that returns an Array[16] of byte values (0-255) +* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written. +* `offset` - (Number) Starting index in `buffer` at which to begin writing. + +Returns `buffer`, if specified, otherwise the string form of the UUID + +Example: Generate string UUID with predefined `random` values + +```javascript +const v4options = { + random: [ + 0x10, 0x91, 0x56, 0xbe, 0xc4, 0xfb, 0xc1, 0xea, + 0x71, 0xb4, 0xef, 0xe1, 0x67, 0x1c, 0x58, 0x36 + ] +}; +uuidv4(v4options); // ⇨ '109156be-c4fb-41ea-b1b4-efe1671c5836' + +``` + +Example: Generate two IDs in a single buffer + +```javascript +const buffer = new Array(); +uuidv4(null, buffer, 0); // ⇨ [ 155, 29, 235, 77, 59, 125, 75, 173, 155, 221, 43, 13, 123, 61, 203, 109 ] +uuidv4(null, buffer, 16); // ⇨ [ 155, 29, 235, 77, 59, 125, 75, 173, 155, 221, 43, 13, 123, 61, 203, 109, 27, 157, 107, 205, 187, 253, 75, 45, 155, 93, 171, 141, 251, 189, 75, 237 ] + +``` + +### Version 5 + +```javascript +const uuidv5 = require('uuid/v5'); + +// Incantations +uuidv5(name, namespace); +uuidv5(name, namespace, buffer); +uuidv5(name, namespace, buffer, offset); +``` + +Generate and return a RFC4122 v5 UUID. + +* `name` - (String | Array[]) "name" to create UUID with +* `namespace` - (String | Array[]) "namespace" UUID either as a String or Array[16] of byte values +* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written. +* `offset` - (Number) Starting index in `buffer` at which to begin writing. Default = 0 + +Returns `buffer`, if specified, otherwise the string form of the UUID + +Example: + +```javascript +uuidv5('hello world', MY_NAMESPACE); // ⇨ '9f282611-e0fd-5650-8953-89c8e342da0b' + +``` + +## Command Line + +UUIDs can be generated from the command line with the `uuid` command. + +```shell +$ uuid +ddeb27fb-d9a0-4624-be4d-4615062daed4 + +$ uuid v1 +02d37060-d446-11e7-a9fa-7bdae751ebe1 +``` + +Type `uuid --help` for usage details + +## Testing + +```shell +npm test +``` + +---- +Markdown generated from [README_js.md](README_js.md) by [![RunMD Logo](http://i.imgur.com/h0FVyzU.png)](https://github.com/broofa/runmd) \ No newline at end of file diff --git a/node_modules/uuid/bin/uuid b/node_modules/uuid/bin/uuid new file mode 100755 index 0000000..502626e --- /dev/null +++ b/node_modules/uuid/bin/uuid @@ -0,0 +1,65 @@ +#!/usr/bin/env node +var assert = require('assert'); + +function usage() { + console.log('Usage:'); + console.log(' uuid'); + console.log(' uuid v1'); + console.log(' uuid v3 '); + console.log(' uuid v4'); + console.log(' uuid v5 '); + console.log(' uuid --help'); + console.log('\nNote: may be "URL" or "DNS" to use the corresponding UUIDs defined by RFC4122'); +} + +var args = process.argv.slice(2); + +if (args.indexOf('--help') >= 0) { + usage(); + process.exit(0); +} +var version = args.shift() || 'v4'; + +switch (version) { + case 'v1': + var uuidV1 = require('../v1'); + console.log(uuidV1()); + break; + + case 'v3': + var uuidV3 = require('../v3'); + + var name = args.shift(); + var namespace = args.shift(); + assert(name != null, 'v3 name not specified'); + assert(namespace != null, 'v3 namespace not specified'); + + if (namespace == 'URL') namespace = uuidV3.URL; + if (namespace == 'DNS') namespace = uuidV3.DNS; + + console.log(uuidV3(name, namespace)); + break; + + case 'v4': + var uuidV4 = require('../v4'); + console.log(uuidV4()); + break; + + case 'v5': + var uuidV5 = require('../v5'); + + var name = args.shift(); + var namespace = args.shift(); + assert(name != null, 'v5 name not specified'); + assert(namespace != null, 'v5 namespace not specified'); + + if (namespace == 'URL') namespace = uuidV5.URL; + if (namespace == 'DNS') namespace = uuidV5.DNS; + + console.log(uuidV5(name, namespace)); + break; + + default: + usage(); + process.exit(1); +} diff --git a/node_modules/uuid/index.js b/node_modules/uuid/index.js new file mode 100644 index 0000000..e96791a --- /dev/null +++ b/node_modules/uuid/index.js @@ -0,0 +1,8 @@ +var v1 = require('./v1'); +var v4 = require('./v4'); + +var uuid = v4; +uuid.v1 = v1; +uuid.v4 = v4; + +module.exports = uuid; diff --git a/node_modules/uuid/lib/bytesToUuid.js b/node_modules/uuid/lib/bytesToUuid.js new file mode 100644 index 0000000..847c482 --- /dev/null +++ b/node_modules/uuid/lib/bytesToUuid.js @@ -0,0 +1,24 @@ +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +var byteToHex = []; +for (var i = 0; i < 256; ++i) { + byteToHex[i] = (i + 0x100).toString(16).substr(1); +} + +function bytesToUuid(buf, offset) { + var i = offset || 0; + var bth = byteToHex; + // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 + return ([bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]]]).join(''); +} + +module.exports = bytesToUuid; diff --git a/node_modules/uuid/lib/md5-browser.js b/node_modules/uuid/lib/md5-browser.js new file mode 100644 index 0000000..9b3b6c7 --- /dev/null +++ b/node_modules/uuid/lib/md5-browser.js @@ -0,0 +1,216 @@ +/* + * Browser-compatible JavaScript MD5 + * + * Modification of JavaScript MD5 + * https://github.com/blueimp/JavaScript-MD5 + * + * Copyright 2011, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * https://opensource.org/licenses/MIT + * + * Based on + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + +'use strict'; + +function md5(bytes) { + if (typeof(bytes) == 'string') { + var msg = unescape(encodeURIComponent(bytes)); // UTF8 escape + bytes = new Array(msg.length); + for (var i = 0; i < msg.length; i++) bytes[i] = msg.charCodeAt(i); + } + + return md5ToHexEncodedArray( + wordsToMd5( + bytesToWords(bytes) + , bytes.length * 8) + ); +} + + +/* +* Convert an array of little-endian words to an array of bytes +*/ +function md5ToHexEncodedArray(input) { + var i; + var x; + var output = []; + var length32 = input.length * 32; + var hexTab = '0123456789abcdef'; + var hex; + + for (i = 0; i < length32; i += 8) { + x = (input[i >> 5] >>> (i % 32)) & 0xFF; + + hex = parseInt(hexTab.charAt((x >>> 4) & 0x0F) + hexTab.charAt(x & 0x0F), 16); + + output.push(hex); + } + return output; +} + +/* +* Calculate the MD5 of an array of little-endian words, and a bit length. +*/ +function wordsToMd5(x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << (len % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var i; + var olda; + var oldb; + var oldc; + var oldd; + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + + var d = 271733878; + + for (i = 0; i < x.length; i += 16) { + olda = a; + oldb = b; + oldc = c; + oldd = d; + + a = md5ff(a, b, c, d, x[i], 7, -680876936); + d = md5ff(d, a, b, c, x[i + 1], 12, -389564586); + c = md5ff(c, d, a, b, x[i + 2], 17, 606105819); + b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330); + a = md5ff(a, b, c, d, x[i + 4], 7, -176418897); + d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426); + c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341); + b = md5ff(b, c, d, a, x[i + 7], 22, -45705983); + a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416); + d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417); + c = md5ff(c, d, a, b, x[i + 10], 17, -42063); + b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162); + a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682); + d = md5ff(d, a, b, c, x[i + 13], 12, -40341101); + c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290); + b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329); + + a = md5gg(a, b, c, d, x[i + 1], 5, -165796510); + d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632); + c = md5gg(c, d, a, b, x[i + 11], 14, 643717713); + b = md5gg(b, c, d, a, x[i], 20, -373897302); + a = md5gg(a, b, c, d, x[i + 5], 5, -701558691); + d = md5gg(d, a, b, c, x[i + 10], 9, 38016083); + c = md5gg(c, d, a, b, x[i + 15], 14, -660478335); + b = md5gg(b, c, d, a, x[i + 4], 20, -405537848); + a = md5gg(a, b, c, d, x[i + 9], 5, 568446438); + d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690); + c = md5gg(c, d, a, b, x[i + 3], 14, -187363961); + b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501); + a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467); + d = md5gg(d, a, b, c, x[i + 2], 9, -51403784); + c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473); + b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734); + + a = md5hh(a, b, c, d, x[i + 5], 4, -378558); + d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463); + c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562); + b = md5hh(b, c, d, a, x[i + 14], 23, -35309556); + a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060); + d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353); + c = md5hh(c, d, a, b, x[i + 7], 16, -155497632); + b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640); + a = md5hh(a, b, c, d, x[i + 13], 4, 681279174); + d = md5hh(d, a, b, c, x[i], 11, -358537222); + c = md5hh(c, d, a, b, x[i + 3], 16, -722521979); + b = md5hh(b, c, d, a, x[i + 6], 23, 76029189); + a = md5hh(a, b, c, d, x[i + 9], 4, -640364487); + d = md5hh(d, a, b, c, x[i + 12], 11, -421815835); + c = md5hh(c, d, a, b, x[i + 15], 16, 530742520); + b = md5hh(b, c, d, a, x[i + 2], 23, -995338651); + + a = md5ii(a, b, c, d, x[i], 6, -198630844); + d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415); + c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905); + b = md5ii(b, c, d, a, x[i + 5], 21, -57434055); + a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571); + d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606); + c = md5ii(c, d, a, b, x[i + 10], 15, -1051523); + b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799); + a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359); + d = md5ii(d, a, b, c, x[i + 15], 10, -30611744); + c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380); + b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649); + a = md5ii(a, b, c, d, x[i + 4], 6, -145523070); + d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379); + c = md5ii(c, d, a, b, x[i + 2], 15, 718787259); + b = md5ii(b, c, d, a, x[i + 9], 21, -343485551); + + a = safeAdd(a, olda); + b = safeAdd(b, oldb); + c = safeAdd(c, oldc); + d = safeAdd(d, oldd); + } + return [a, b, c, d]; +} + +/* +* Convert an array bytes to an array of little-endian words +* Characters >255 have their high-byte silently ignored. +*/ +function bytesToWords(input) { + var i; + var output = []; + output[(input.length >> 2) - 1] = undefined; + for (i = 0; i < output.length; i += 1) { + output[i] = 0; + } + var length8 = input.length * 8; + for (i = 0; i < length8; i += 8) { + output[i >> 5] |= (input[(i / 8)] & 0xFF) << (i % 32); + } + + return output; +} + +/* +* Add integers, wrapping at 2^32. This uses 16-bit operations internally +* to work around bugs in some JS interpreters. +*/ +function safeAdd(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +/* +* Bitwise rotate a 32-bit number to the left. +*/ +function bitRotateLeft(num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)); +} + +/* +* These functions implement the four basic operations the algorithm uses. +*/ +function md5cmn(q, a, b, x, s, t) { + return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b); +} +function md5ff(a, b, c, d, x, s, t) { + return md5cmn((b & c) | ((~b) & d), a, b, x, s, t); +} +function md5gg(a, b, c, d, x, s, t) { + return md5cmn((b & d) | (c & (~d)), a, b, x, s, t); +} +function md5hh(a, b, c, d, x, s, t) { + return md5cmn(b ^ c ^ d, a, b, x, s, t); +} +function md5ii(a, b, c, d, x, s, t) { + return md5cmn(c ^ (b | (~d)), a, b, x, s, t); +} + +module.exports = md5; diff --git a/node_modules/uuid/lib/md5.js b/node_modules/uuid/lib/md5.js new file mode 100644 index 0000000..7044b87 --- /dev/null +++ b/node_modules/uuid/lib/md5.js @@ -0,0 +1,25 @@ +'use strict'; + +var crypto = require('crypto'); + +function md5(bytes) { + if (typeof Buffer.from === 'function') { + // Modern Buffer API + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } + } else { + // Pre-v4 Buffer API + if (Array.isArray(bytes)) { + bytes = new Buffer(bytes); + } else if (typeof bytes === 'string') { + bytes = new Buffer(bytes, 'utf8'); + } + } + + return crypto.createHash('md5').update(bytes).digest(); +} + +module.exports = md5; diff --git a/node_modules/uuid/lib/rng-browser.js b/node_modules/uuid/lib/rng-browser.js new file mode 100644 index 0000000..6361fb8 --- /dev/null +++ b/node_modules/uuid/lib/rng-browser.js @@ -0,0 +1,34 @@ +// Unique ID creation requires a high quality random # generator. In the +// browser this is a little complicated due to unknown quality of Math.random() +// and inconsistent support for the `crypto` API. We do the best we can via +// feature-detection + +// getRandomValues needs to be invoked in a context where "this" is a Crypto +// implementation. Also, find the complete implementation of crypto on IE11. +var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || + (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); + +if (getRandomValues) { + // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto + var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef + + module.exports = function whatwgRNG() { + getRandomValues(rnds8); + return rnds8; + }; +} else { + // Math.random()-based (RNG) + // + // If all else fails, use Math.random(). It's fast, but is of unspecified + // quality. + var rnds = new Array(16); + + module.exports = function mathRNG() { + for (var i = 0, r; i < 16; i++) { + if ((i & 0x03) === 0) r = Math.random() * 0x100000000; + rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; + } + + return rnds; + }; +} diff --git a/node_modules/uuid/lib/rng.js b/node_modules/uuid/lib/rng.js new file mode 100644 index 0000000..58f0dc9 --- /dev/null +++ b/node_modules/uuid/lib/rng.js @@ -0,0 +1,8 @@ +// Unique ID creation requires a high quality random # generator. In node.js +// this is pretty straight-forward - we use the crypto API. + +var crypto = require('crypto'); + +module.exports = function nodeRNG() { + return crypto.randomBytes(16); +}; diff --git a/node_modules/uuid/lib/sha1-browser.js b/node_modules/uuid/lib/sha1-browser.js new file mode 100644 index 0000000..5758ed7 --- /dev/null +++ b/node_modules/uuid/lib/sha1-browser.js @@ -0,0 +1,89 @@ +// Adapted from Chris Veness' SHA1 code at +// http://www.movable-type.co.uk/scripts/sha1.html +'use strict'; + +function f(s, x, y, z) { + switch (s) { + case 0: return (x & y) ^ (~x & z); + case 1: return x ^ y ^ z; + case 2: return (x & y) ^ (x & z) ^ (y & z); + case 3: return x ^ y ^ z; + } +} + +function ROTL(x, n) { + return (x << n) | (x>>> (32 - n)); +} + +function sha1(bytes) { + var K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6]; + var H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0]; + + if (typeof(bytes) == 'string') { + var msg = unescape(encodeURIComponent(bytes)); // UTF8 escape + bytes = new Array(msg.length); + for (var i = 0; i < msg.length; i++) bytes[i] = msg.charCodeAt(i); + } + + bytes.push(0x80); + + var l = bytes.length/4 + 2; + var N = Math.ceil(l/16); + var M = new Array(N); + + for (var i=0; i>> 0; + e = d; + d = c; + c = ROTL(b, 30) >>> 0; + b = a; + a = T; + } + + H[0] = (H[0] + a) >>> 0; + H[1] = (H[1] + b) >>> 0; + H[2] = (H[2] + c) >>> 0; + H[3] = (H[3] + d) >>> 0; + H[4] = (H[4] + e) >>> 0; + } + + return [ + H[0] >> 24 & 0xff, H[0] >> 16 & 0xff, H[0] >> 8 & 0xff, H[0] & 0xff, + H[1] >> 24 & 0xff, H[1] >> 16 & 0xff, H[1] >> 8 & 0xff, H[1] & 0xff, + H[2] >> 24 & 0xff, H[2] >> 16 & 0xff, H[2] >> 8 & 0xff, H[2] & 0xff, + H[3] >> 24 & 0xff, H[3] >> 16 & 0xff, H[3] >> 8 & 0xff, H[3] & 0xff, + H[4] >> 24 & 0xff, H[4] >> 16 & 0xff, H[4] >> 8 & 0xff, H[4] & 0xff + ]; +} + +module.exports = sha1; diff --git a/node_modules/uuid/lib/sha1.js b/node_modules/uuid/lib/sha1.js new file mode 100644 index 0000000..0b54b25 --- /dev/null +++ b/node_modules/uuid/lib/sha1.js @@ -0,0 +1,25 @@ +'use strict'; + +var crypto = require('crypto'); + +function sha1(bytes) { + if (typeof Buffer.from === 'function') { + // Modern Buffer API + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } + } else { + // Pre-v4 Buffer API + if (Array.isArray(bytes)) { + bytes = new Buffer(bytes); + } else if (typeof bytes === 'string') { + bytes = new Buffer(bytes, 'utf8'); + } + } + + return crypto.createHash('sha1').update(bytes).digest(); +} + +module.exports = sha1; diff --git a/node_modules/uuid/lib/v35.js b/node_modules/uuid/lib/v35.js new file mode 100644 index 0000000..8b066cc --- /dev/null +++ b/node_modules/uuid/lib/v35.js @@ -0,0 +1,57 @@ +var bytesToUuid = require('./bytesToUuid'); + +function uuidToBytes(uuid) { + // Note: We assume we're being passed a valid uuid string + var bytes = []; + uuid.replace(/[a-fA-F0-9]{2}/g, function(hex) { + bytes.push(parseInt(hex, 16)); + }); + + return bytes; +} + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + var bytes = new Array(str.length); + for (var i = 0; i < str.length; i++) { + bytes[i] = str.charCodeAt(i); + } + return bytes; +} + +module.exports = function(name, version, hashfunc) { + var generateUUID = function(value, namespace, buf, offset) { + var off = buf && offset || 0; + + if (typeof(value) == 'string') value = stringToBytes(value); + if (typeof(namespace) == 'string') namespace = uuidToBytes(namespace); + + if (!Array.isArray(value)) throw TypeError('value must be an array of bytes'); + if (!Array.isArray(namespace) || namespace.length !== 16) throw TypeError('namespace must be uuid string or an Array of 16 byte values'); + + // Per 4.3 + var bytes = hashfunc(namespace.concat(value)); + bytes[6] = (bytes[6] & 0x0f) | version; + bytes[8] = (bytes[8] & 0x3f) | 0x80; + + if (buf) { + for (var idx = 0; idx < 16; ++idx) { + buf[off+idx] = bytes[idx]; + } + } + + return buf || bytesToUuid(bytes); + }; + + // Function#name is not settable on some platforms (#270) + try { + generateUUID.name = name; + } catch (err) { + } + + // Pre-defined namespaces, per Appendix C + generateUUID.DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; + generateUUID.URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; + + return generateUUID; +}; diff --git a/node_modules/uuid/package.json b/node_modules/uuid/package.json new file mode 100644 index 0000000..feb1127 --- /dev/null +++ b/node_modules/uuid/package.json @@ -0,0 +1,96 @@ +{ + "_from": "uuid", + "_id": "uuid@3.3.3", + "_inBundle": false, + "_integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", + "_location": "/uuid", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "uuid", + "name": "uuid", + "escapedName": "uuid", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "_shasum": "4568f0216e78760ee1dbf3a4d2cf53e224112866", + "_spec": "uuid", + "_where": "/home/cake/rpclib", + "bin": { + "uuid": "./bin/uuid" + }, + "browser": { + "./lib/rng.js": "./lib/rng-browser.js", + "./lib/sha1.js": "./lib/sha1-browser.js", + "./lib/md5.js": "./lib/md5-browser.js" + }, + "bugs": { + "url": "https://github.com/kelektiv/node-uuid/issues" + }, + "bundleDependencies": false, + "commitlint": { + "extends": [ + "@commitlint/config-conventional" + ] + }, + "contributors": [ + { + "name": "Robert Kieffer", + "email": "robert@broofa.com" + }, + { + "name": "Christoph Tavan", + "email": "dev@tavan.de" + }, + { + "name": "AJ ONeal", + "email": "coolaj86@gmail.com" + }, + { + "name": "Vincent Voyer", + "email": "vincent@zeroload.net" + }, + { + "name": "Roman Shtylman", + "email": "shtylman@gmail.com" + } + ], + "deprecated": false, + "description": "RFC4122 (v1, v4, and v5) UUIDs", + "devDependencies": { + "@commitlint/cli": "8.1.0", + "@commitlint/config-conventional": "8.1.0", + "eslint": "6.2.0", + "husky": "3.0.4", + "mocha": "6.2.0", + "runmd": "1.2.1", + "standard-version": "7.0.0" + }, + "homepage": "https://github.com/kelektiv/node-uuid#readme", + "keywords": [ + "uuid", + "guid", + "rfc4122" + ], + "license": "MIT", + "name": "uuid", + "repository": { + "type": "git", + "url": "git+https://github.com/kelektiv/node-uuid.git" + }, + "scripts": { + "commitmsg": "commitlint -E HUSKY_GIT_PARAMS", + "md": "runmd --watch --output=README.md README_js.md", + "prepare": "runmd --output=README.md README_js.md", + "release": "standard-version", + "test": "mocha test/test.js" + }, + "version": "3.3.3" +} diff --git a/node_modules/uuid/v1.js b/node_modules/uuid/v1.js new file mode 100644 index 0000000..d84c0f4 --- /dev/null +++ b/node_modules/uuid/v1.js @@ -0,0 +1,109 @@ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html + +var _nodeId; +var _clockseq; + +// Previous uuid creation time +var _lastMSecs = 0; +var _lastNSecs = 0; + +// See https://github.com/broofa/node-uuid for API details +function v1(options, buf, offset) { + var i = buf && offset || 0; + var b = buf || []; + + options = options || {}; + var node = options.node || _nodeId; + var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; + + // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + if (node == null || clockseq == null) { + var seedBytes = rng(); + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [ + seedBytes[0] | 0x01, + seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] + ]; + } + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } + + // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); + + // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; + + // Time since last uuid creation (in msecs) + var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; + + // Per 4.2.1.2, Bump clockseq on clock regression + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } + + // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } + + // Per 4.2.1.2 Throw error if too many uuids are requested + if (nsecs >= 10000) { + throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; + + // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + msecs += 12219292800000; + + // `time_low` + var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; + + // `time_mid` + var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; + + // `time_high_and_version` + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + b[i++] = tmh >>> 16 & 0xff; + + // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + b[i++] = clockseq >>> 8 | 0x80; + + // `clock_seq_low` + b[i++] = clockseq & 0xff; + + // `node` + for (var n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf ? buf : bytesToUuid(b); +} + +module.exports = v1; diff --git a/node_modules/uuid/v3.js b/node_modules/uuid/v3.js new file mode 100644 index 0000000..ee7e14c --- /dev/null +++ b/node_modules/uuid/v3.js @@ -0,0 +1,4 @@ +var v35 = require('./lib/v35.js'); +var md5 = require('./lib/md5'); + +module.exports = v35('v3', 0x30, md5); \ No newline at end of file diff --git a/node_modules/uuid/v4.js b/node_modules/uuid/v4.js new file mode 100644 index 0000000..1f07be1 --- /dev/null +++ b/node_modules/uuid/v4.js @@ -0,0 +1,29 @@ +var rng = require('./lib/rng'); +var bytesToUuid = require('./lib/bytesToUuid'); + +function v4(options, buf, offset) { + var i = buf && offset || 0; + + if (typeof(options) == 'string') { + buf = options === 'binary' ? new Array(16) : null; + options = null; + } + options = options || {}; + + var rnds = options.random || (options.rng || rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ++ii) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || bytesToUuid(rnds); +} + +module.exports = v4; diff --git a/node_modules/uuid/v5.js b/node_modules/uuid/v5.js new file mode 100644 index 0000000..4945baf --- /dev/null +++ b/node_modules/uuid/v5.js @@ -0,0 +1,3 @@ +var v35 = require('./lib/v35.js'); +var sha1 = require('./lib/sha1'); +module.exports = v35('v5', 0x50, sha1); diff --git a/package-lock.json b/package-lock.json index 7842971..e067de8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3944,6 +3944,11 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + }, "v8-compile-cache": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", diff --git a/package.json b/package.json index df1666f..56c06db 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,11 @@ "name": "rpclib", "version": "1.0.0", "description": "", - "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "build": "npm run clean; npm run tsc; npm run webpack", + "tsc": "tsc", + "webpack": "webpack --config src/frontend/webpack.prod.js --progress --colors", + "clean": "rm -rf lib" }, "author": "", "license": "ISC", @@ -19,6 +21,7 @@ "webpack-cli": "^3.3.5" }, "dependencies": { - "bsock": "^0.1.9" + "bsock": "^0.1.9", + "uuid": "^3.3.3" } } diff --git a/src/backend/RPCExporter.ts b/src/backend/RPCSocketServer.ts similarity index 54% rename from src/backend/RPCExporter.ts rename to src/backend/RPCSocketServer.ts index 7da6284..95ff246 100644 --- a/src/backend/RPCExporter.ts +++ b/src/backend/RPCSocketServer.ts @@ -1,11 +1,49 @@ -import { SubscriptionResponse, SuccessResponse, ErrorResponse } from "../../../../vendor/generic/Types"; +import http = require('http'); +import bsock = require('bsock'); + import * as uuid from "uuid/v4" +import { Socket } from "./RPCSocketServer" type rpcType = 'hook' | 'unhook' | 'call' type visibility = 'public' | 'private' export type Outcome = "Success" | "Error" +/* Responses */ +export class Response{ + constructor( + public message?:string + ){} +} + +export class SuccessResponse extends Response{ + result:Outcome = "Success" + + constructor( + message?:string + ){ + super(message) + } +} + +export class ErrorResponse extends Response{ + result:Outcome = "Error" + + constructor( + message: string = "Unknown error" + ){ + super(message) + } +} + +export class SubscriptionResponse extends SuccessResponse{ + constructor( + public uid: string, + message?:string + ){ + super(message) + } +} export type UnhookFunction = (uid:string) => Promise export type callbackFunction = (...args) => Promise export type AsyncFunction = (...args) => Promise @@ -98,7 +136,7 @@ export const rpcToRpcinfo = (rpc : socketioRPC, owner: string):RpcInfo => { } } -export const rpcHooker = (socket, owner:string, RPCs: socketioRPC[], makeUnique = true):ExtendedRpcInfo[] => { +export const rpcHooker = (socket: Socket, owner:string, RPCs: socketioRPC[], makeUnique = true):ExtendedRpcInfo[] => { const suffix = makeUnique?"-"+uuid().substr(0,4):"" return RPCs.map(rpc => rpcToRpcinfo(rpc, owner)) .map(info => { @@ -137,10 +175,79 @@ const hookGenerator = (rpc:hookRPC): HookInfo['generator'] => { }`) } -function extractArgs(f:Function):string[]{ +const extractArgs = (f:Function):string[] => { let fn = String(f) let args = fn.substr(0, fn.indexOf(")")) args = args.substr(fn.indexOf("(")+1) let ret = args.split(",") return ret +} + + +type OnFunction = (type: 'error' | 'close', f: (e?:any)=>void) => Socket + +export type Socket = { + port: number + hook: (rpcname: string, ...args: any[]) => Socket + unhook: (rpcname:string) => Socket + call: (rpcname:string, ...args: any[]) => Promise + fire: (rpcname:string, ...args: any[]) => Promise + on: OnFunction + destroy: ()=>void + close: ()=>void +} + +export type RPCSocketConf = { + connectionHandler: (socket:Socket) => void + errorHandler: (socket:Socket) => (error:any) => void + closeHandler: (socket:Socket) => () => void +} + +export class RPCSocketServer{ + + private io = bsock.createServer() + private wsServer = http.createServer() + + constructor( + private port:number, + private rpcExporters: RPCExporter[] = [], + private conf: RPCSocketConf = { + errorHandler: (socket:Socket) => (error:any) => { socket.destroy(); console.error(error) }, + closeHandler: (socket:Socket) => () => { console.log("Socket closing") }, + connectionHandler: (socket:Socket) => { console.log("New websocket connection in port "+socket.port) } + } + ){ + this.startWebsocket() + } + + private startWebsocket(){ + try{ + this.io.attach(this.wsServer) + this.io.on('socket', (socket:Socket) => { + socket.on('error', this.conf.errorHandler(socket)) + socket.on('close', this.conf.closeHandler(socket)) + this.initApis(socket) + }) + this.wsServer.listen(this.port) + }catch(e){ + //@ts-ignore + this.errorHandler(undefined)("Unable to connect to socket") + } + } + + protected initApis(socket){ + const adminRPCs:socketioRPC[] = [ + { + name: 'info', + type: 'call', + visibility: 'private', + func: async () => rpcInfos + } + ] + + const rpcInfos:ExtendedRpcInfo[] = [ + ...rpcHooker(socket, "Admin", adminRPCs, false), + ...this.rpcExporters.flatMap(exporter => rpcHooker(socket, exporter.name, exporter.exportRPCs())) + ] + } } \ No newline at end of file diff --git a/src/frontend/RPCallable.ts b/src/frontend/RPCaller.ts similarity index 80% rename from src/frontend/RPCallable.ts rename to src/frontend/RPCaller.ts index bdd5060..7980222 100644 --- a/src/frontend/RPCallable.ts +++ b/src/frontend/RPCaller.ts @@ -1,5 +1,4 @@ -import { parseSubResponse, parseResponse } from "frontblock-generic/Types"; -import { ExtendedRpcInfo, UnhookFunction, callbackFunction, AsyncFunction } from "frontblock-generic/RPC"; +import { ExtendedRpcInfo, UnhookFunction, callbackFunction, AsyncFunction } from "../backend/RPCSocketServer"; var bsock = require('bsock') //fix args with defaults like "force = true" -> "force" @@ -7,6 +6,10 @@ function stripAfterEquals(str:string){ return str.split("=")[0] } +type RPCReceiver = { + [RPCGroup in string]: any +} + /** * Dynamic library to communicate with FrontblockService remotely * @@ -14,20 +17,14 @@ function stripAfterEquals(str:string){ * Will ask it's service for available RPCs and parse them into methods of this object * for convenient access. */ -export class RPCallable{ +export class RPCaller implements RPCReceiver{ private socket - constructor(){ - this.socket = bsock.connect(20000, 'localhost', false/*tls*/) - this.init() + constructor(port:number, server: string, tls: boolean = false){ + this.socket = bsock.connect(port, server, tls) } - // need this-context for eval-magic below - // DO NOT REMOVE. They're not really unused - private parseSubResponse = parseSubResponse - private parseResponse = parseResponse - - private async init(){ + async connect(){ const info:ExtendedRpcInfo[] = await this.info() info.forEach(i => { let f: any @@ -64,8 +61,7 @@ export class RPCallable{ const argParams = fnArgs.map(stripAfterEquals).join(",") return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => { const r = await this.socket.call("`+fnName+`", `+argParams+`) - const res = await this.parseSubResponse(r); - if(res.uid != null){ + if(r.uid != null){ this.socket.hook(res.uid, callback) } return res @@ -80,12 +76,9 @@ export class RPCallable{ return eval( `( () => async (`+headerArgs+`) => { const r = await this.socket.call("`+fnName+`", `+argParams+`) - const res = await this.parseResponse(r) this.socket.unhook(`+argParams+`) return res } )()` ) } -} - -window['rpc'] = new RPCallable() \ No newline at end of file +} \ No newline at end of file diff --git a/src/frontend/webpack.prod.js b/src/frontend/webpack.prod.js index 656a567..6443998 100644 --- a/src/frontend/webpack.prod.js +++ b/src/frontend/webpack.prod.js @@ -4,10 +4,10 @@ const TerserPlugin = require('terser-webpack-plugin'); module.exports = { mode: 'production', target: "web", - entry: path.resolve(__dirname, 'module.ts'), + entry: path.resolve(__dirname, 'RPCaller.ts'), output: { - path: path.resolve(__dirname, '../../dist'), - filename: 'FrontendPlugin.js', + path: path.resolve(__dirname, '../../lib'), + filename: 'RPCaller.min.js', libraryTarget: 'commonjs', }, resolve: { @@ -30,11 +30,5 @@ module.exports = { ], }, externals: { - '@angular/core': '@angular/core', - '@angular/common': '@angular/common', - '@angular/router': '@angular/router', - '@angular/animations': '@angular/animations', - '@angular/forms': '@angular/forms', - '@clr/angular': '@clr/angular' } } diff --git a/test/test.ts b/test/test.ts new file mode 100644 index 0000000..32a3611 --- /dev/null +++ b/test/test.ts @@ -0,0 +1,19 @@ +import { RPCSocketServer } from '../src/backend/RPCSocketServer' +//@ts-ignore +import {RPCaller} from '../src/frontend/RPCaller' + +new RPCSocketServer(20000, [{ + name: "HelloWorldRPCGroup", + exportRPCs: () => [{ + type: 'call', + name: 'echo', + func: async (s:string) => s, + visibility: 'private' + }] +}] ) + +const caller = new RPCaller(20000, 'localhost') +caller.connect().then(_ => { + caller.info().then(console.log) + caller["HelloWorldRPCGroup"].echo("x").then(console.log) +}) diff --git a/tsconfig.json b/tsconfig.json index 4c77987..ae05096 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,6 +9,6 @@ "strict": true, "experimentalDecorators": true }, - "include": ["src/backend/**/*"], - "exclude": ["node_modules", "**/__tests__/*"], + "include": ["src/backend/**/*", "test/**/*"], + "exclude": ["node_modules", "**/__tests__/*", "src/frontend/**/*"] } \ No newline at end of file