@faulpeltz/dertunnel 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,10 @@
1
+ # DerTunnel client
2
+
3
+ A client library for <https://github.com/faulpeltz/dertunnel>
4
+
5
+ Intended for creating public tunnel endpoints from code for e.g. running integration tests.
6
+
7
+ ## License
8
+
9
+ (c) faulpeltz
10
+ [MIT](https://choosealicense.com/licenses/mit/)
package/client.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ export declare type ClientOptions = {
2
+ user: string;
3
+ token: string;
4
+ serviceHost: string;
5
+ servicePort?: number;
6
+ localServer?: string;
7
+ localPort: number;
8
+ endpoint?: string;
9
+ endpointPrefix?: string;
10
+ ignoreCertErrors?: boolean;
11
+ waitForInitialConnection?: boolean;
12
+ onConnected?: (assignedEndpoint: string) => void | Promise<void>;
13
+ onError?: (err: string) => void | Promise<void>;
14
+ };
15
+
16
+ export declare function connectTunnel(opts: ClientOptions): Promise<() => void>;
package/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";var M=Object.create;var v=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var W=Object.getPrototypeOf,q=Object.prototype.hasOwnProperty;var F=(e,t)=>{for(var r in t)v(e,r,{get:t[r],enumerable:!0})},P=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of G(t))!q.call(e,i)&&i!==r&&v(e,i,{get:()=>t[i],enumerable:!(n=V(t,i))||n.enumerable});return e};var J=(e,t,r)=>(r=e!=null?M(W(e)):{},P(t||!e||!e.__esModule?v(r,"default",{value:e,enumerable:!0}):r,e)),K=e=>P(v({},"__esModule",{value:!0}),e);var X={};F(X,{connectTunnel:()=>z});module.exports=K(X);var j=require("net"),A=J(require("tls"));var S=(o=>(o[o.HELLO_REQ=1]="HELLO_REQ",o[o.HELLO_RESP=2]="HELLO_RESP",o[o.END=3]="END",o[o.SERVER_OPEN=4]="SERVER_OPEN",o[o.SERVER_CLOSE=5]="SERVER_CLOSE",o[o.CLIENT_CLOSE=6]="CLIENT_CLOSE",o[o.PING=7]="PING",o[o.PONG=8]="PONG",o[o.SERVER_DATA=65]="SERVER_DATA",o[o.CLIENT_DATA=66]="CLIENT_DATA",o))(S||{});function T(e){return{name:Object.keys(S).find(t=>S[t]===e)??"UNKNOWN",isBinary:!!(e&64)}}var R=1;var Q=1*1024*1024,p=12,O=70,C=80,k=0,I=1,y=2,w=4,N=8,B=!!process.env.DERTUNNEL_DEBUG,D=class{constructor(t){this.onMessage=t}buffer=void 0;async receive(t){let r=this.buffer?Buffer.concat([this.buffer,t]):t,n=0;for(;n<r.length;){if(r.length<n+p)return this.buffer=r,!0;if(r[n+k]!=O||r[n+I]!=C)return this.reset(),!1;let i=r.readUint16LE(n+y),f=r.readUint32LE(n+w),d=r.readUint32LE(n+N),u=d+p+n;if(d>Q)return this.reset(),!1;if(r.length>=u)try{let a=r.slice(n+p,u);B&&H(i,f,a,!1),await this.onMessage(i,f,a)}catch{return this.reset(),!1}else break;n=u}return this.buffer=r.length>n?r.slice(n):void 0,!0}reset(){this.buffer=void 0}};function g(e,t,r,n){let i=Buffer.isBuffer(n)?n:n?Buffer.from(JSON.stringify(n)):void 0,f=Buffer.allocUnsafe(p+(i?i.length:0));f.writeUint8(O,k),f.writeUint8(C,I),f.writeUint16LE(t,y),f.writeUint32LE(r,w),f.writeUint32LE(i?i.length:0,N),i?.copy(f,p,0);let d=e.write(f);return B&&H(t,r,i,!0),d}function h(e){return JSON.parse(e.toString("utf8"))}function H(e,t,r,n){let{name:i,isBinary:f}=T(e);console.debug(`[msg-${n?"out":"in"} ${i} ${t>0?t:""}] ${r?f?`- ${r.length} payload bytes`:r.toString("utf8"):"- empty"}`)}function _(){let e,t,r=new Promise((n,i)=>{e=n,t=i});return r.resolve=e,r.reject=t,r}var U="service.";async function z(e){let t=!1,r=!1,n,i=300,f=1.4,d=1e4,b={reconnectTime:i};if(!e.endpoint&&!e.endpointPrefix)throw new Error("Must either define 'endpoint' or 'endpointPrefix'");if(!e.serviceHost||!e.user||!e.token||!e.localPort)throw new Error("Missing required options");let u=_(),a=e.serviceHost;a.startsWith(U)||(a=U+a);let o=()=>{n?.destroy(),n=A.default.connect({timeout:1e4,host:a,port:e.servicePort||443,servername:a,...e.ignoreCertErrors?{checkServerIdentity:(l,L)=>{}}:{}},()=>{n.setKeepAlive(!0,5e3),g(n,1,0,{version:R,user:e.user,token:e.token,endpoint:e.endpoint,endpointPrefix:e.endpointPrefix})}),n.setMaxListeners(0);let m=new Map,$=new D(async(l,L,E)=>{if(!t&&l===2){let c=h(E);if(!c.success){n?.destroy();let s="Server connection error: "+c.error;u.reject(new Error(s)),e.onError?.(s);return}e.onConnected?.(c.endpoint||""),u.resolve(),t=!0,b.reconnectTime=i}if(l===3){n?.destroy();let c=h(E);c.error&&e.onError?.(c.error);return}if(t){if(l===7)g(n,8,0);else if(l===65){let c=m.get(L);c&&(c.bytesSent+=E.length,c.write(E))}else if(l===4){let c=h(E),s=(0,j.createConnection)({host:e.localServer??"localhost",port:e.localPort,allowHalfOpen:!1});s.channelId=c.channelId,s.bytesReceived=s.bytesSent=0,m.set(c.channelId,s),s.on("close",()=>{m.delete(c.channelId),g(n,6,0,{channelId:s.channelId})}),s.on("data",x=>{s.bytesReceived+=x.length,!g(n,66,s.channelId,x)&&!s.isPaused()&&(s.pause(),n.once("drain",()=>{s.resume()}))}),s.on("error",x=>{})}else if(l===5){let c=h(E),s=m.get(c.channelId);s&&(m.delete(c.channelId),s.end(()=>s.destroy()))}}});n.on("error",l=>{t=!1,!r&&(u.reject(l),e.onError?.("Server connection error: "+l.message))}),n.on("close",()=>{t=!1,m.forEach(l=>l.destroy()),!r&&(setTimeout(o,b.reconnectTime),b.reconnectTime=Math.min(d,b.reconnectTime*f))}),n.on("data",l=>{r||$.receive(l)||n?.destroy()})};return o(),e.waitForInitialConnection!==!1&&await u,()=>{r=!0,n?.destroy()}}0&&(module.exports={connectTunnel});
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@faulpeltz/dertunnel",
3
+ "version": "0.1.0",
4
+ "description": "A client for the dertunnel public endpoint forwarder",
5
+ "main": "./index.js",
6
+ "typings": "./client.d.ts",
7
+ "scripts": {
8
+ },
9
+ "keywords": [
10
+ "tunnel", "dertunnel"
11
+ ],
12
+ "author": "faulpeltz",
13
+ "license": "MIT",
14
+ "devDependencies": {
15
+ },
16
+ "dependencies": {
17
+ }
18
+ }