diff --git a/package-lock.json b/package-lock.json index bfafd25..f90d51a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "juno", + "name": "juno-node", "version": "0.0.0", "lockfileVersion": 1, "requires": true, diff --git a/src/connection/inet-socket-connection.ts b/src/connection/inet-socket-connection.ts new file mode 100644 index 0000000..08d1521 --- /dev/null +++ b/src/connection/inet-socket-connection.ts @@ -0,0 +1,43 @@ +import { Socket, createConnection } from 'net'; +import BaseConnection from './base-connection'; + +export default class InetSocketConnection extends BaseConnection { + client?: Socket; + host: string; + port: number; + + constructor(host: string, port: number) { + super(); + this.host = host; + this.port = port; + } + + setupConnection(): Promise { + return new Promise(resolve => { + this.client = createConnection(this.port, this.host); + this.client.on('data', (data) => { + const dataLines = data.toString().split(/\r?\n/); + dataLines.map((data) => { + if (data) { + this.onData(Buffer.from(data)) + } + }); + }); + this.client.on('connect', () => { + resolve(); + }); + }); + } + + async closeConnection() { + this.client?.destroy(); + } + + send(message: Buffer): Promise { + return new Promise(resolve => { + this.client?.write(message, () => { + resolve(); + }); + }); + } +} diff --git a/src/connection/unix-socket-connection.ts b/src/connection/unix-socket-connection.ts index e6a0735..f94800d 100644 --- a/src/connection/unix-socket-connection.ts +++ b/src/connection/unix-socket-connection.ts @@ -1,8 +1,8 @@ -import * as net from 'net'; +import { Socket, createConnection } from 'net'; import BaseConnection from './base-connection'; -export default class SocketConnection extends BaseConnection { - client?: net.Socket; +export default class UnixSocketConnection extends BaseConnection { + client?: Socket; sockPath: string; constructor(sockPath: string) { @@ -12,7 +12,7 @@ export default class SocketConnection extends BaseConnection { setupConnection(): Promise { return new Promise(resolve => { - this.client = net.createConnection(this.sockPath); + this.client = createConnection(this.sockPath); this.client.on('data', (data) => { const dataLines = data.toString().split(/\r?\n/); dataLines.map((data) => { diff --git a/src/juno-node.ts b/src/juno-node.ts index 14d9825..7bd118d 100644 --- a/src/juno-node.ts +++ b/src/juno-node.ts @@ -1,3 +1,5 @@ +import { isIP } from 'net'; +import { promises as fsPromises } from 'fs'; import { BaseProtocol } from './protocol/base-protocol'; import BaseConnection from './connection/base-connection'; import { JsonProtocol } from './protocol/json-protocol'; @@ -8,7 +10,8 @@ import { TriggerHookRequest, JunoMessage } from './models/messages'; -import SocketConnection from './connection/unix-socket-connection'; +import UnixSocketConnection from './connection/unix-socket-connection'; +import InetSocketConnection from './connection/inet-socket-connection'; export default class JunoModule { @@ -27,8 +30,38 @@ export default class JunoModule { // this.connection.setOnDataListener(this.onDataHandler); } - public static default(socketPath: string): JunoModule { - return new JunoModule(new SocketConnection(socketPath), new JsonProtocol()); + public static async default(socketPath: string) { + const [ host, port ] = socketPath.split(':'); + + if (isIP(host) && !isNaN(Number(port))) { + return this.fromInetSocket(host, Number(port)); + } + if ( (await fsPromises.lstat(socketPath)).isSocket() ) { + return this.fromUnixSocket(socketPath); + } + + throw new Error('Invalid socket object. Only unix domain sockets and Inet sockets are allowed'); + + } + + public static async fromUnixSocket(path: string) { + // Return Error if invoked from windows + if (process.platform == 'win32') { + throw new Error('Unix sockets are not supported on windows'); + } + if ( (await fsPromises.lstat(path)).isSocket() ) { + return new JunoModule(new UnixSocketConnection(path), new JsonProtocol()); + } + + throw new Error('Invalid unix socket path'); + } + + public static async fromInetSocket(host: string, port: number) { + if (isIP(host) && !isNaN(Number(port))) { + return new JunoModule(new InetSocketConnection(host, port), new JsonProtocol()); + } + + throw new Error('Invalid Inet socket address. Use the format `{host}:{port}`') } public async initialize(