diff --git a/.eslintignore b/.eslintignore
index 581c5c65e..4a5064d0d 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -3,13 +3,20 @@ src/**/*.d.ts
src/**/*.js.map
src/Kuzzle.js
+src/KuzzleError.js
src/controllers/Auth.js
src/controllers/Document.js
src/controllers/Base.js
src/core/security/User.js
src/core/security/Profile.js
src/core/security/Role.js
+src/protocols/abstract/Base.js
+src/protocols/abstract/Realtime.js
+src/protocols/Http.js
+src/protocols/WebSocket.js
+src/protocols/index.js
src/utils/interfaces.js
+src/core/KuzzleEventEmitter.js
src/core/searchResult/SearchResultBase.js
src/core/searchResult/Document.js
src/core/searchResult/Profile.js
diff --git a/.gitignore b/.gitignore
index d0ef8a16d..875b9e4c4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,13 +31,20 @@ test-*.js
*.js.map
index.js
src/Kuzzle.js
+src/KuzzleError.js
src/controllers/Auth.js
src/controllers/Document.js
src/controllers/Base.js
src/core/security/User.js
src/core/security/Profile.js
src/core/security/Role.js
+src/protocols/abstract/Base.js
+src/protocols/abstract/Realtime.js
+src/protocols/Http.js
+src/protocols/WebSocket.js
+src/protocols/index.js
src/utils/interfaces.js
+src/core/KuzzleEventEmitter.js
src/core/searchResult/SearchResultBase.js
src/core/searchResult/Document.js
src/core/searchResult/Profile.js
diff --git a/doc/7/core-classes/kuzzle-error/properties/index.md b/doc/7/core-classes/kuzzle-error/properties/index.md
index 1b5655e92..63b07a4f9 100644
--- a/doc/7/core-classes/kuzzle-error/properties/index.md
+++ b/doc/7/core-classes/kuzzle-error/properties/index.md
@@ -14,3 +14,6 @@ order: 10
| `message` |
string
| Error message |
| `status` | number
| Error status code |
| `stack` | string
| Error stacktrace (only in development mode) |
+| `id` | string
| Error unique identifier |
+| `code` | string
| Error unique code |
+
diff --git a/doc/7/essentials/error-handling/index.md b/doc/7/essentials/error-handling/index.md
index f19e943a8..fa56caac4 100644
--- a/doc/7/essentials/error-handling/index.md
+++ b/doc/7/essentials/error-handling/index.md
@@ -15,7 +15,9 @@ All SDK methods return a promise, that can be rejected with a `KuzzleError` valu
| Property | Type | Description |
| -------- | ----------------- | ------------------------------------------------------------------------------------------ |
| `status` | number
| Status following [HTTP Standards](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) |
-| `stack` | string
| Error stacktrace (Only in development mode) |
+| `stack` | string
| Error stacktrace (Only in development mode) | `id` | string
| Error unique identifier |
+| `code` | string
| Error unique code |
+
You can find a detailed list of possible errors messages and statuses in the [documentation API](/core/2/api/essentials/error-handling).
diff --git a/doc/7/protocols/http/constructor/index.md b/doc/7/protocols/http/constructor/index.md
index d5ff3892f..60609c4fc 100644
--- a/doc/7/protocols/http/constructor/index.md
+++ b/doc/7/protocols/http/constructor/index.md
@@ -30,7 +30,8 @@ Http protocol connection options.
| Property | Type
(default) | Description |
| --------------- | -------------------------------- | ----------------------------------- |
| `port` | number
(`7512`) | Kuzzle server port |
-| `sslConnection` | boolean
(`false`) | Use SSL to connect to Kuzzle server |
+| `sslConnection` | boolean
(`false`) | Use SSL to connect to Kuzzle server |
+| `ssl` | boolean
(`false`) | Use SSL to connect to Kuzzle server. Defaults to `true` for ports 443 and 7443. |
| `customRoutes` | object
(`{}`) | Add custom routes |
| `timeout` | number
(`0`) | Connection timeout in milliseconds (`0` means no timeout) |
diff --git a/doc/7/protocols/websocket/constructor/index.md b/doc/7/protocols/websocket/constructor/index.md
index 736df3deb..5393f00e2 100644
--- a/doc/7/protocols/websocket/constructor/index.md
+++ b/doc/7/protocols/websocket/constructor/index.md
@@ -31,9 +31,10 @@ WebSocket protocol connection options.
| ------------------- | -------------------------------- | -------------------------------------------------------------------------------------------- |
| `autoReconnect` | boolean
(`true`) | Automatically reconnect to kuzzle after a `disconnected` event |
| `port` | number
(`7512`) | Kuzzle server port |
-| `headers` | object
(`{}`) | Connection HTTP headers (e.g. origin, subprotocols, ...)
**(Not supported by browsers)** |
+| `headers` | object
(`{}`) | Connection custom HTTP headers (e.g. origin, subprotocols, ...)
**(Not supported by browsers)** |
| `reconnectionDelay` | number
(`1000`) | Number of milliseconds between reconnection attempts |
-| `sslConnection` | boolean
(`false`) | Use SSL to connect to Kuzzle server |
+| `sslConnection` | boolean
(`false`) | Use SSL to connect to Kuzzle server |
+| `ssl` | boolean
(`false`) | Use SSL to connect to Kuzzle server. Defaults to `true` for ports 443 and 7443. |
## Return
diff --git a/package.json b/package.json
index 9e6a88c71..781b4ee45 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,9 @@
"test:functional": "cucumber-js --exit --fail-fast",
"test:lint": "npm run test:lint:js && npm run test:lint:ts",
"test:lint:js": "eslint --max-warnings=0 ./src ./test ./features",
+ "test:lint:js:fix": "eslint --max-warnings=0 ./src ./test ./features --fix",
"test:lint:ts": "eslint ./src --ext .ts --config .eslintc-ts.json",
+ "test:lint:ts:fix": "eslint ./src --ext .ts --config .eslintc-ts.json --fix",
"build": "npm run build-ts && node build.js",
"build-ts": "tsc --build tsconfig.json",
"doc": "docker-compose -f doc/docker-compose.yml up",
diff --git a/src/Kuzzle.ts b/src/Kuzzle.ts
index 98a27138e..6d25a3fde 100644
--- a/src/Kuzzle.ts
+++ b/src/Kuzzle.ts
@@ -693,7 +693,4 @@ Discarded request: ${JSON.stringify(request)}`));
dequeuingProcess();
}
-
}
-
-module.exports = { Kuzzle };
diff --git a/src/KuzzleError.js b/src/KuzzleError.js
deleted file mode 100644
index fd9ee4ce3..000000000
--- a/src/KuzzleError.js
+++ /dev/null
@@ -1,20 +0,0 @@
-'use strict';
-
-class KuzzleError extends Error {
- constructor (apiError) {
- super(apiError.message);
-
- this.status = apiError.status;
- this.stack = apiError.stack;
- this.id = apiError.id;
- this.code = apiError.code;
-
- // PartialError
- if (this.status === 206) {
- this.errors = apiError.errors;
- this.count = apiError.count;
- }
- }
-}
-
-module.exports = KuzzleError;
diff --git a/src/KuzzleError.ts b/src/KuzzleError.ts
new file mode 100644
index 000000000..b65910f2c
--- /dev/null
+++ b/src/KuzzleError.ts
@@ -0,0 +1,51 @@
+'use strict';
+
+/**
+ * Standard Kuzzle error.
+ *
+ * @see https://docs.kuzzle.io/core/2/api/essentials/error-handling/
+ */
+export class KuzzleError extends Error {
+ /**
+ * Http status code
+ */
+ public status: number;
+ /**
+ * Stacktrace (only if NODE_ENV=development)
+ */
+ public stack?: string;
+ /**
+ * Unique ID
+ */
+ public id: string;
+ /**
+ * Code
+ */
+ public code: number;
+
+ /**
+ * Associated errors
+ * (PartialError only)
+ */
+ public errors?: Array;
+ /**
+ * Number of associated errors
+ * (PartialError only)
+ */
+ public count?: number;
+
+ constructor (apiError) {
+ super(apiError.message);
+
+ this.status = apiError.status;
+ this.stack = apiError.stack;
+ this.id = apiError.id;
+ this.code = apiError.code;
+
+ // PartialError
+ if (this.status === 206) {
+ this.errors = apiError.errors;
+ this.count = apiError.count;
+ }
+ }
+}
diff --git a/src/controllers/Auth.ts b/src/controllers/Auth.ts
index 7ae066f9e..9ed867c18 100644
--- a/src/controllers/Auth.ts
+++ b/src/controllers/Auth.ts
@@ -520,5 +520,3 @@ export class AuthController extends BaseController {
});
}
}
-
-module.exports = { AuthController };
diff --git a/src/controllers/Base.ts b/src/controllers/Base.ts
index b67d63f58..8115fc82a 100644
--- a/src/controllers/Base.ts
+++ b/src/controllers/Base.ts
@@ -40,5 +40,3 @@ export class BaseController {
return this._kuzzle.query(request, options);
}
}
-
-module.exports = { BaseController };
diff --git a/src/controllers/Document.ts b/src/controllers/Document.ts
index 34141a911..88066b4a7 100644
--- a/src/controllers/Document.ts
+++ b/src/controllers/Document.ts
@@ -801,5 +801,3 @@ export class DocumentController extends BaseController {
.then(response => response.result);
}
}
-
-module.exports = { DocumentController };
diff --git a/src/core/KuzzleEventEmitter.js b/src/core/KuzzleEventEmitter.ts
similarity index 92%
rename from src/core/KuzzleEventEmitter.js
rename to src/core/KuzzleEventEmitter.ts
index e88ee825c..1003a5ce6 100644
--- a/src/core/KuzzleEventEmitter.js
+++ b/src/core/KuzzleEventEmitter.ts
@@ -1,12 +1,20 @@
class Listener {
+ public fn: (...any) => any;
+ public once: boolean;
+
constructor(fn, once = false) {
this.fn = fn;
this.once = once;
}
}
-class KuzzleEventEmitter {
- constructor() {
+/**
+ * @todo proper TS conversion
+ */
+export class KuzzleEventEmitter {
+ private _events: Map>;
+
+ constructor () {
this._events = new Map();
}
@@ -98,7 +106,7 @@ class KuzzleEventEmitter {
return this;
}
- removeAllListeners (eventName) {
+ removeAllListeners (eventName?: string) {
if (eventName) {
this._events.delete(eventName);
}
diff --git a/src/core/searchResult/SearchResultBase.ts b/src/core/searchResult/SearchResultBase.ts
index b183d54b2..c48ea9c71 100644
--- a/src/core/searchResult/SearchResultBase.ts
+++ b/src/core/searchResult/SearchResultBase.ts
@@ -189,6 +189,3 @@ export class SearchResultBase implements SearchResult {
return nextSearchResult;
}
}
-
-
-module.exports = { SearchResultBase };
diff --git a/src/protocols/Http.js b/src/protocols/Http.ts
similarity index 78%
rename from src/protocols/Http.js
rename to src/protocols/Http.ts
index e7f1d86fe..95e79574a 100644
--- a/src/protocols/Http.js
+++ b/src/protocols/Http.ts
@@ -1,10 +1,35 @@
'use strict';
-const staticHttpRoutes = require('./routes.json');
-const { KuzzleAbstractProtocol } = require('./abstract/Base');
+import staticHttpRoutes from './routes.json';
+import { KuzzleAbstractProtocol } from './abstract/Base';
+import { HttpRoutes, JSONObject, KuzzleRequest } from '../utils/interfaces';
-class HttpProtocol extends KuzzleAbstractProtocol {
- constructor(host, options = {}) {
+export default class HttpProtocol extends KuzzleAbstractProtocol {
+ private _routes: HttpRoutes;
+ private _timeout: number;
+ private _customRoutes: HttpRoutes;
+
+ /**
+ * @param host Kuzzle server hostname or IP
+ * @param options Http connection options
+ * - `customRoutes` Add custom routes
+ * - `port` Kuzzle server port (default: `7512`)
+ * - `ssl` Use SSL to connect to Kuzzle server. Default `false` unless port is 443 or 7443.
+ * - `timeout` Connection timeout in milliseconds (default: `0`)
+ */
+ constructor(
+ host: string,
+ options: {
+ port?: number;
+ /**
+ * @deprecated Use `ssl` instead
+ */
+ sslConnection?: boolean;
+ ssl?: boolean;
+ customRoutes?: HttpRoutes;
+ timeout?: number
+ } = {}
+ ) {
super(host, options, 'http');
if (typeof host !== 'string' || host === '') {
@@ -15,10 +40,10 @@ class HttpProtocol extends KuzzleAbstractProtocol {
this._timeout = options.timeout || 0;
- this.customRoutes = options.customRoutes || {};
+ this._customRoutes = options.customRoutes || {};
- for (const controller of Object.keys(this.customRoutes)) {
- const definition = this.customRoutes[controller];
+ for (const controller of Object.keys(this._customRoutes)) {
+ const definition = this._customRoutes[controller];
for (const action of Object.keys(definition)) {
const route = definition[action];
@@ -35,35 +60,49 @@ class HttpProtocol extends KuzzleAbstractProtocol {
}
}
- // @deprecated
+ /**
+ * @deprecated Use `routes` instead
+ */
get http () {
return this.routes;
}
- get routes () {
+ /**
+ * Returns a list of available routes
+ */
+ get routes (): HttpRoutes {
return this._routes;
}
- get protocol () {
+ /**
+ * `http` or `https`
+ */
+ get protocol (): string {
return this.ssl ? 'https' : 'http';
}
- get connected () {
+ /**
+ * Always returns `true`
+ */
+ get connected (): true {
return true;
}
- get timeout () {
+ /**
+ * Connection timeout in milliseconds
+ */
+ get timeout (): number {
return this._timeout;
}
- set timeout (timeout) {
+ set timeout (timeout: number) {
this._timeout = timeout;
}
/**
* Connect to the server
*/
- connect () {
+ connect (): Promise {
if (this.state === 'ready') {
return Promise.resolve();
}
@@ -92,7 +131,6 @@ class HttpProtocol extends KuzzleAbstractProtocol {
.then(({ result: res, error: err }) => {
if (! err) {
this._routes = this._constructRoutes(res.serverInfo.kuzzle.api.routes);
- this._staticRoutes = false;
return;
}
@@ -114,13 +152,13 @@ class HttpProtocol extends KuzzleAbstractProtocol {
throw error;
})
.then(() => {
- this._routes = Object.assign(this._routes, this.customRoutes);
+ this._routes = Object.assign(this._routes, this._customRoutes);
// Client is ready
this.clientConnected();
})
.catch(err => {
- const connectionError = new Error(`Unable to connect to kuzzle server at ${this.host}:${this.port}`);
+ const connectionError: any = new Error(`Unable to connect to kuzzle server at ${this.host}:${this.port}`);
connectionError.internal = err;
this.emit('networkError', connectionError);
@@ -134,19 +172,19 @@ class HttpProtocol extends KuzzleAbstractProtocol {
* @param {Object} data
* @returns {Promise}
*/
- send (data, options = {}) {
- const route = this.routes[data.controller]
- && this.routes[data.controller][data.action];
+ send (request: KuzzleRequest, options: JSONObject = {}) {
+ const route = this.routes[request.controller]
+ && this.routes[request.controller][request.action];
if (! route) {
- const error = new Error(`No URL found for "${data.controller}:${data.action}".`);
- this.emit(data.requestId, { status: 400, error });
+ const error = new Error(`No URL found for "${request.controller}:${request.action}".`);
+ this.emit(request.requestId, { status: 400, error });
return;
}
const method = options.verb || route.verb;
- const payload = {
+ const payload: any = {
action: undefined,
body: undefined,
collection: undefined,
@@ -160,8 +198,8 @@ class HttpProtocol extends KuzzleAbstractProtocol {
};
const queryArgs = {};
- for (const key of Object.keys(data)) {
- const value = data[key];
+ for (const key of Object.keys(request)) {
+ const value = request[key];
if (key === 'body') {
if (method === 'GET') {
@@ -191,7 +229,7 @@ class HttpProtocol extends KuzzleAbstractProtocol {
let matches = regex.exec(url);
while (matches) {
- const urlParam = data[ matches[1] ];
+ const urlParam = request[ matches[1] ];
// check if an url param is missing (eg: "/:index/_create)
if (!urlParam) {
@@ -201,9 +239,9 @@ class HttpProtocol extends KuzzleAbstractProtocol {
return;
}
- url = url.replace(regex, `/${encodeURIComponent(data[matches[1]])}`);
+ url = url.replace(regex, `/${encodeURIComponent(request[matches[1]])}`);
- delete(queryArgs[ matches[1] ]);
+ delete queryArgs[matches[1]];
matches = regex.exec(url);
}
@@ -242,10 +280,11 @@ class HttpProtocol extends KuzzleAbstractProtocol {
.catch(error => this.emit(payload.requestId, {error}));
}
- _sendHttpRequest (method, path, payload = {}) {
+ _sendHttpRequest (method, path, payload: any = {}) {
if (typeof XMLHttpRequest === 'undefined') {
// NodeJS implementation, using http.request:
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
const httpClient = require('min-req-promise');
if (path[0] !== '/') {
@@ -328,8 +367,8 @@ class HttpProtocol extends KuzzleAbstractProtocol {
return routes;
}, {});
- for (const controller of Object.keys(this.customRoutes)) {
- apiRoutes[controller] = this.customRoutes[controller];
+ for (const controller of Object.keys(this._customRoutes)) {
+ apiRoutes[controller] = this._customRoutes[controller];
}
return apiRoutes;
@@ -371,5 +410,3 @@ function getCorrectRoute (routes) {
// will be in the query string
return sameLength ? getRoute : shortestRoute;
}
-
-module.exports = HttpProtocol;
diff --git a/src/protocols/WebSocket.js b/src/protocols/WebSocket.ts
similarity index 67%
rename from src/protocols/WebSocket.js
rename to src/protocols/WebSocket.ts
index f2d05e1fb..25acbebe3 100644
--- a/src/protocols/WebSocket.js
+++ b/src/protocols/WebSocket.ts
@@ -1,11 +1,59 @@
'use strict';
-const KuzzleError = require('../KuzzleError');
-const BaseProtocolRealtime = require('./abstract/Realtime');
+import { KuzzleError } from '../KuzzleError';
+import { BaseProtocolRealtime } from './abstract/Realtime';
+import { JSONObject, KuzzleRequest } from '../utils/interfaces';
-class WebSocketProtocol extends BaseProtocolRealtime {
+export default class WebSocketProtocol extends BaseProtocolRealtime {
+ private WebSocketClient: any;
+ private options: any;
+ private client: any;
+ private lasturl: any;
- constructor(host, options = {}) {
+ /**
+ * Automatically reconnect after a connection loss
+ */
+ public autoReconnect: boolean;
+ /**
+ * `true` if the socket is open
+ */
+ public connected: boolean;
+ /**
+ * Kuzzle server host or IP
+ */
+ public host: string;
+ /**
+ * Kuzzle server port
+ */
+ public port: number;
+ /**
+ * `true` if ssl is active
+ */
+ public ssl: boolean;
+
+ /**
+ * @param host Kuzzle server hostname or IP
+ * @param options WebSocket connection options
+ * - `autoReconnect` Automatically reconnect to kuzzle after a `disconnected` event. (default: `true`)
+ * - `port` Kuzzle server port (default: `7512`)
+ * - `headers` Connection custom HTTP headers (Not supported by browsers)
+ * - `reconnectionDelay` Number of milliseconds between reconnection attempts (default: `1000`)
+ * - `ssl` Use SSL to connect to Kuzzle server. Default `false` unless port is 443 or 7443.
+ */
+ constructor(
+ host: string,
+ options: {
+ autoReconnect?: boolean;
+ port?: number;
+ headers?: JSONObject;
+ reconnectionDelay?: number;
+ /**
+ * @deprecated Use `ssl` instead
+ */
+ sslConnection?: boolean;
+ ssl?: boolean;
+ } = {}
+ ) {
super(host, options, 'ws');
if (typeof host !== 'string' || host === '') {
@@ -39,7 +87,7 @@ class WebSocketProtocol extends BaseProtocolRealtime {
/**
* Connect to the websocket server
*/
- connect () {
+ connect (): Promise {
return new Promise((resolve, reject) => {
const url = `${this.ssl ? 'wss' : 'ws'}://${this.host}:${this.port}`;
@@ -79,7 +127,7 @@ class WebSocketProtocol extends BaseProtocolRealtime {
// do not forward a connection close error if no
// connection has been previously established
else if (this.wasConnected) {
- const error = new Error(reason);
+ const error: any = new Error(reason);
error.status = status;
this.clientNetworkError(error);
@@ -127,9 +175,9 @@ class WebSocketProtocol extends BaseProtocolRealtime {
*
* @param {Object} payload
*/
- send (payload) {
+ send (request: KuzzleRequest) {
if (this.client && this.client.readyState === this.client.OPEN) {
- this.client.send(JSON.stringify(payload));
+ this.client.send(JSON.stringify(request));
}
}
@@ -148,5 +196,3 @@ class WebSocketProtocol extends BaseProtocolRealtime {
super.close();
}
}
-
-module.exports = WebSocketProtocol;
diff --git a/src/protocols/abstract/Base.js b/src/protocols/abstract/Base.ts
similarity index 65%
rename from src/protocols/abstract/Base.js
rename to src/protocols/abstract/Base.ts
index 258c6082e..d16040eba 100644
--- a/src/protocols/abstract/Base.js
+++ b/src/protocols/abstract/Base.ts
@@ -1,12 +1,26 @@
'use strict';
-const KuzzleError = require('../../KuzzleError');
-const { uuidv4 } = require('../../utils/uuidv4');
-const { KuzzleEventEmitter } = require('../../core/KuzzleEventEmitter');
-const PendingRequest = require('./PendingRequest');
-
-class KuzzleAbstractProtocol extends KuzzleEventEmitter {
- constructor (host, options = {}, name = undefined) {
+import { KuzzleError } from '../../KuzzleError';
+import { uuidv4 } from '../../utils/uuidv4';
+import { KuzzleEventEmitter } from '../../core/KuzzleEventEmitter';
+import { PendingRequest } from './PendingRequest';
+import { KuzzleRequest, JSONObject } from '../../utils/interfaces';
+
+/**
+ * @todo proper TS conversion
+ */
+export abstract class KuzzleAbstractProtocol extends KuzzleEventEmitter {
+ private _pendingRequests: Map;
+ private _host: string;
+ private _name: string;
+ private _port: number;
+ private _ssl: boolean;
+
+ public id: string;
+
+ public state: string;
+
+ constructor (host: string, options: JSONObject = {}, name: string = undefined) {
super();
this._pendingRequests = new Map();
@@ -14,7 +28,23 @@ class KuzzleAbstractProtocol extends KuzzleEventEmitter {
this._name = name;
const port = parseInt(options.port, 10);
this._port = isNaN(port) ? 7512 : port;
- this._ssl = typeof options.sslConnection === 'boolean' ? options.sslConnection : false;
+
+ if (options.ssl !== undefined && options.sslConnection !== undefined) {
+ throw new Error('Both "ssl" and "sslConnection" options are set. Use only "ssl".');
+ }
+
+ if (typeof options.ssl === 'boolean') {
+ this._ssl = options.ssl;
+ }
+ else if (typeof options.sslConnection === 'boolean') {
+ this._ssl = options.sslConnection;
+ }
+ else if (port === 443 || port === 7443) {
+ this._ssl = true;
+ }
+ else {
+ this._ssl = false;
+ }
this.id = uuidv4();
this.state = 'offline';
@@ -52,27 +82,14 @@ class KuzzleAbstractProtocol extends KuzzleEventEmitter {
return this._pendingRequests;
}
- /**
- * @abstract
- * @returns {Promise}
- */
- connect () {
- throw new Error('Method "connect" is not implemented');
- }
+ abstract connect (): Promise
- /**
- * @abstract
- * @param request
- * @returns {Promise}
- */
- send () {
- throw new Error('Method "send" is not implemented');
- }
+ abstract send (request: KuzzleRequest, options: JSONObject): void
/**
* Called when the client's connection is established
*/
- clientConnected (state, wasConnected) {
+ clientConnected (state?: string, wasConnected?: boolean) {
this.state = state || 'ready';
this.emit(wasConnected && 'reconnect' || 'connect');
}
@@ -136,7 +153,4 @@ Discarded request: ${JSON.stringify(request)}`));
this._pendingRequests.clear();
}
-
}
-
-module.exports = { KuzzleAbstractProtocol };
diff --git a/src/protocols/abstract/PendingRequest.js b/src/protocols/abstract/PendingRequest.js
index 852ea9a0b..73aa5dfbd 100644
--- a/src/protocols/abstract/PendingRequest.js
+++ b/src/protocols/abstract/PendingRequest.js
@@ -20,4 +20,4 @@ class PendingRequest {
}
}
-module.exports = PendingRequest;
+module.exports = { PendingRequest };
diff --git a/src/protocols/abstract/Realtime.js b/src/protocols/abstract/Realtime.ts
similarity index 72%
rename from src/protocols/abstract/Realtime.js
rename to src/protocols/abstract/Realtime.ts
index 0dab94019..74bb34cc0 100644
--- a/src/protocols/abstract/Realtime.js
+++ b/src/protocols/abstract/Realtime.ts
@@ -1,10 +1,16 @@
'use strict';
-const { KuzzleAbstractProtocol } = require('./Base');
+import { KuzzleAbstractProtocol } from './Base';
-class BaseProtocolRealtime extends KuzzleAbstractProtocol {
- constructor (host, options = {}) {
- super(host, options);
+export abstract class BaseProtocolRealtime extends KuzzleAbstractProtocol {
+ protected _autoReconnect: boolean;
+ protected _reconnectionDelay: number;
+ protected wasConnected: boolean;
+ protected stopRetryingToConnect: boolean;
+ protected retrying: boolean;
+
+ constructor (host, options: any = {}, name: string) {
+ super(host, options, name);
this._autoReconnect = typeof options.autoReconnect === 'boolean' ? options.autoReconnect : true;
this._reconnectionDelay = typeof options.reconnectionDelay === 'number' ? options.reconnectionDelay : 1000;
@@ -18,18 +24,23 @@ class BaseProtocolRealtime extends KuzzleAbstractProtocol {
return this._autoReconnect;
}
- get reconnectionDelay () {
+ /**
+ * Number of milliseconds between reconnection attempts
+ */
+ get reconnectionDelay (): number {
return this._reconnectionDelay;
}
- connect() {
+ connect (): Promise {
this.state = 'connecting';
+
+ return Promise.resolve();
}
/**
* Called when the client's connection is established
*/
- clientConnected() {
+ clientConnected () {
super.clientConnected('connected', this.wasConnected);
this.state = 'connected';
@@ -40,7 +51,7 @@ class BaseProtocolRealtime extends KuzzleAbstractProtocol {
/**
* Called when the client's connection is closed
*/
- clientDisconnected() {
+ clientDisconnected () {
this.clear();
this.emit('disconnect');
}
@@ -54,8 +65,7 @@ class BaseProtocolRealtime extends KuzzleAbstractProtocol {
this.state = 'offline';
this.clear();
- const connectionError = new Error(`Unable to connect to kuzzle server at ${this.host}:${this.port}`);
- connectionError.internal = error;
+ const connectionError = new Error(`Unable to connect to kuzzle server at ${this.host}:${this.port}: ${error.message} (ws status=${error.status})`);
this.emit('networkError', connectionError);
@@ -90,5 +100,3 @@ class BaseProtocolRealtime extends KuzzleAbstractProtocol {
return this.state === 'connected';
}
}
-
-module.exports = BaseProtocolRealtime;
diff --git a/src/protocols/index.js b/src/protocols/index.js
deleted file mode 100644
index 1e39ea546..000000000
--- a/src/protocols/index.js
+++ /dev/null
@@ -1,9 +0,0 @@
-'use strict';
-
-const Http = require('./Http');
-const WebSocket = require('./WebSocket');
-
-module.exports = {
- Http,
- WebSocket
-};
diff --git a/src/protocols/index.ts b/src/protocols/index.ts
new file mode 100644
index 000000000..51c13cd4a
--- /dev/null
+++ b/src/protocols/index.ts
@@ -0,0 +1,2 @@
+export { default as WebSocket } from './WebSocket';
+export { default as Http } from './Http';
diff --git a/src/utils/interfaces.ts b/src/utils/interfaces.ts
index fe4cc1f89..075464398 100644
--- a/src/utils/interfaces.ts
+++ b/src/utils/interfaces.ts
@@ -197,3 +197,40 @@ export interface DocumentHit extends Document {
*/
_score: number;
}
+
+/**
+ * HTTP routes definition format
+ * @example
+ * {
+ * : {
+ * : { , }
+ * }
+ * }
+ *
+ * {
+ * 'my-plugin/my-controller': {
+ * action: { verb: 'GET', url: '/some/url' },
+ * action2: { verb: 'GET', url: '/some/url/with/:parameter' }
+ * }
+ * }
+ */
+export interface HttpRoutes {
+ /**
+ * Controller name
+ */
+ [key: string]: {
+ /**
+ * Action name
+ */
+ [key: string]: {
+ /**
+ * HTTP verb
+ */
+ verb: string,
+ /**
+ * URL
+ */
+ url: string
+ }
+ }
+}
diff --git a/test/protocol/Base.test.js b/test/protocol/Base.test.js
index bd2652459..4955524a7 100644
--- a/test/protocol/Base.test.js
+++ b/test/protocol/Base.test.js
@@ -1,9 +1,9 @@
-const
- should = require('should'),
- sinon = require('sinon'),
- KuzzleError = require('../../src/KuzzleError'),
- { KuzzleAbstractProtocol } = require('../../src/protocols/abstract/Base'),
- PendingRequest = require('../../src/protocols/abstract/PendingRequest');
+const should = require('should');
+const sinon = require('sinon');
+
+const { KuzzleError } = require('../../src/KuzzleError');
+const { KuzzleAbstractProtocol } = require('../../src/protocols/abstract/Base');
+const { PendingRequest } = require('../../src/protocols/abstract/PendingRequest');
describe('Common Protocol', () => {
let
@@ -25,6 +25,30 @@ describe('Common Protocol', () => {
should(protocol.port).be.eql(443);
});
+ it('should use ssl option if available and fallback to sslConnection option', () => {
+ protocol = new KuzzleAbstractProtocol('somewhere', { ssl: true });
+
+ should(protocol.ssl).be.true();
+
+ protocol = new KuzzleAbstractProtocol('somewhere', { sslConnection: true });
+
+ should(protocol.ssl).be.true();
+ });
+
+ it('should use ssl connection when port is 443 or 7443 and option is not defined', () => {
+ protocol = new KuzzleAbstractProtocol('somewhere', { port: 443 });
+
+ should(protocol.ssl).be.true();
+
+ protocol = new KuzzleAbstractProtocol('somewhere', { port: 7443 });
+
+ should(protocol.ssl).be.true();
+
+ protocol = new KuzzleAbstractProtocol('somewhere', { port: 4242 });
+
+ should(protocol.ssl).be.false();
+ });
+
it('should use 7512 when no port is given or when port is not a parseable number', () => {
protocol = new KuzzleAbstractProtocol('somewhere', { port: 'foobar' });
@@ -91,7 +115,7 @@ describe('Common Protocol', () => {
const pending = protocol.pendingRequests.get('bar');
- pending.should.be.an.instanceOf(PendingRequest).and.match({request});
+ should(pending).be.instanceOf(PendingRequest).and.match({request});
});
it('should fire a "queryError" event and reject if an error occurred', () => {
diff --git a/test/protocol/Http.test.js b/test/protocol/Http.test.js
index d435a1b1b..18e122f08 100644
--- a/test/protocol/Http.test.js
+++ b/test/protocol/Http.test.js
@@ -3,7 +3,7 @@ const should = require('should');
const sinon = require('sinon');
const staticHttpRoutes = require('../../src/protocols/routes.json');
-const Http = require('../../src/protocols/Http');
+const { default: Http } = require('../../src/protocols/Http');
describe('HTTP networking module', () => {
let protocol;
@@ -557,7 +557,7 @@ describe('HTTP networking module', () => {
beforeEach(() => {
httpRequestStub = sinon.stub().resolves({body: JSON.stringify(mockResponseBody)});
- const MockHttp = proxyquire('../../src/protocols/Http', {
+ const { default: MockHttp } = proxyquire('../../src/protocols/Http', {
'min-req-promise': {request: httpRequestStub}
});
@@ -663,9 +663,7 @@ describe('HTTP networking module', () => {
return xhrStub;
};
- protocol = new Http('address', {
- port: 1234
- });
+ protocol = new Http('address', { port: 1234 });
});
afterEach(() => {
@@ -829,13 +827,14 @@ describe('HTTP networking module', () => {
}
},
};
-
- protocol.customRoutes = {
+ const customRoutes = {
foo: {
list: { verb: 'GET', url: '/overwrite/me/master' }
}
};
+ protocol = new Http('address', { port: 1234, customRoutes });
+
const routes = protocol._constructRoutes(publicApi);
should(routes.foo.list.url).be.eql('/overwrite/me/master');
diff --git a/test/protocol/WebSocket.test.js b/test/protocol/WebSocket.test.js
index cfd3d0989..205f0d443 100644
--- a/test/protocol/WebSocket.test.js
+++ b/test/protocol/WebSocket.test.js
@@ -1,10 +1,10 @@
-const
- should = require('should'),
- sinon = require('sinon'),
- lolex = require('lolex'),
- NodeWS = require('ws'),
- WS = require('../../src/protocols/WebSocket'),
- windowMock = require('../mocks/window.mock');
+const should = require('should');
+const sinon = require('sinon');
+const lolex = require('lolex');
+const NodeWS = require('ws');
+
+const { default: WS } = require('../../src/protocols/WebSocket');
+const windowMock = require('../mocks/window.mock');
describe('WebSocket networking module', () => {
let
@@ -246,8 +246,6 @@ describe('WebSocket networking module', () => {
clock.tick(10);
should(cb).be.calledOnce();
should(cb.firstCall.args[0]).be.an.instanceOf(Error);
- should(cb.firstCall.args[0].internal.status).be.equal(4666);
- should(cb.firstCall.args[0].internal.message).be.equal('foobar');
should(websocket.listeners('networkError').length).be.eql(1);
websocket.clear.should.be.calledOnce();
@@ -259,8 +257,6 @@ describe('WebSocket networking module', () => {
clock.tick(10);
should(cb).be.calledOnce();
should(cb.firstCall.args[0]).be.an.instanceOf(Error);
- should(cb.firstCall.args[0].internal.status).be.equal(4666);
- should(cb.firstCall.args[0].internal.message).be.equal('foobar');
should(websocket.listeners('networkError').length).be.eql(1);
websocket.clear.should.be.calledOnce();
});
diff --git a/tsconfig.json b/tsconfig.json
index 1ea049850..4af52bb73 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -7,7 +7,8 @@
"moduleResolution": "node",
"sourceMap": true,
"baseUrl": ".",
- "resolveJsonModule": true
+ "resolveJsonModule": true,
+ "esModuleInterop": true
},
"rootDir": "src/",
"include": [