diff --git a/.gitignore b/.gitignore index bec018fe..05133408 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,6 @@ node_modules .nyc_output coverage_e2e coverage_unit -*.code-workspace -dist *.DS_Store +dist +*.code-workspace diff --git a/lib/DBSQLClient.ts b/lib/DBSQLClient.ts index c60ebeb7..2a32c821 100644 --- a/lib/DBSQLClient.ts +++ b/lib/DBSQLClient.ts @@ -17,6 +17,11 @@ import StatusFactory from './factory/StatusFactory'; import HiveDriverError from './errors/HiveDriverError'; import { buildUserAgentString, definedOrError } from './utils'; import PlainHttpAuthentication from './connection/auth/PlainHttpAuthentication'; +import XhrConnection from './connection/connections/XhrConnection'; + +function isNodejs() { + return typeof 'process' !== 'undefined' && process && process.versions && process.versions.node; +} export default class DBSQLClient extends EventEmitter implements IDBSQLClient { private client: TCLIService.Client | null; @@ -33,11 +38,15 @@ export default class DBSQLClient extends EventEmitter implements IDBSQLClient { constructor() { super(); - this.connectionProvider = new HttpConnection(); - this.authProvider = new NoSaslAuthentication(); + if (isNodejs()) { + this.connectionProvider = new HttpConnection(); + } else { + this.connectionProvider = new XhrConnection(); + } this.statusFactory = new StatusFactory(); this.client = null; this.connection = null; + this.authProvider = new NoSaslAuthentication(); } private getConnectionOptions(options: IDBSQLConnectionOptions): IConnectionOptions { @@ -53,18 +62,30 @@ export default class DBSQLClient extends EventEmitter implements IDBSQLClient { } async connect(options: IDBSQLConnectionOptions): Promise { - this.authProvider = new PlainHttpAuthentication({ - username: 'token', - password: options.token, - headers: { - 'User-Agent': buildUserAgentString(options.clientId), - }, - }); + let opts; + if (isNodejs()) { + opts = { + username: 'token', + password: options.token, + headers: { + 'User-Agent': buildUserAgentString(options.clientId), + }, + }; + } else { + opts = { + username: 'token', + password: options.token, + }; + } + this.authProvider = new PlainHttpAuthentication(opts); this.connection = await this.connectionProvider.connect(this.getConnectionOptions(options), this.authProvider); - this.client = this.thrift.createClient(TCLIService, this.connection.getConnection()); - + if (isNodejs()) { + this.client = this.thrift.createClient(TCLIService, this.connection.getConnection()); + } else { + this.client = this.thrift.createXHRClient(TCLIService, this.connection.getConnection()); + } this.connection.getConnection().on('error', (error: Error) => { this.emit('error', error); }); diff --git a/lib/connection/connections/XhrConnection.ts b/lib/connection/connections/XhrConnection.ts new file mode 100644 index 00000000..40fcf338 --- /dev/null +++ b/lib/connection/connections/XhrConnection.ts @@ -0,0 +1,39 @@ +import thrift from 'thrift'; + +import IThriftConnection from '../contracts/IThriftConnection'; +import IConnectionProvider from '../contracts/IConnectionProvider'; +import IConnectionOptions from '../contracts/IConnectionOptions'; +import IAuthentication from '../contracts/IAuthentication'; +import XhrTransport from '../transports/XhrTransport'; + +export default class XhrConnection implements IConnectionProvider, IThriftConnection { + private thrift = thrift; + + private connection: any; + + connect(options: IConnectionOptions, authProvider: IAuthentication): Promise { + const xhrTransport = new XhrTransport({ + transport: thrift.TBufferedTransport, + protocol: thrift.TBinaryProtocol, + headers: { + 'Content-Type': 'application/vnd.apache.thrift.binary', + }, + ...options.options, + }); + return authProvider.authenticate(xhrTransport).then(() => { + this.connection = this.thrift.createXHRConnection(options.host, options.port, xhrTransport.getOptions()); + return this; + }); + } + + isConnected(): boolean { + if (this.connection) { + return true; + } + return false; + } + + getConnection() { + return this.connection; + } +} diff --git a/lib/connection/transports/XhrTransport.ts b/lib/connection/transports/XhrTransport.ts new file mode 100644 index 00000000..bd264171 --- /dev/null +++ b/lib/connection/transports/XhrTransport.ts @@ -0,0 +1,36 @@ +import ITransport from '../contracts/ITransport'; + +export default class XhrTransport implements ITransport { + private xhrOptions: object; + + constructor(httpOptions: object = {}) { + this.xhrOptions = httpOptions; + } + + getTransport(): any { + return this.xhrOptions; + } + + setOptions(option: string, value: any) { + this.xhrOptions = { + ...this.xhrOptions, + [option]: value, + }; + } + + getOptions(): object { + return this.xhrOptions; + } + + connect() {} + + addListener() {} + + removeListener() {} + + write() {} + + end() {} + + emit() {} +}