Skip to content

Commit

Permalink
Enabled ts strict mode and fixed linting errors
Browse files Browse the repository at this point in the history
  • Loading branch information
chrste90 committed Apr 6, 2018
1 parent 2574fc2 commit 558585c
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 47 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ sudo: false
node_js:
- 8
script:
npm test
- npm run lint
- npm test
branches:
only:
- master
Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
"module": "./src/index.js",
"typings": "./src/index.d.ts",
"scripts": {
"clean": "node clean",
"test": "ng test",
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"docs": "compodoc projects/ngx-mqtt/src -p tsconfig.json",
"serve:docs": "http-server documentation"
},
Expand Down
14 changes: 9 additions & 5 deletions projects/ngx-mqtt/src/lib/mqtt.model.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as MQTT from 'mqtt';
import { IClientOptions, IClientPublishOptions, IPacket } from 'mqtt';

export enum MqttConnectionState {
CLOSED,
CONNECTING,
CONNECTED
}

export interface MqttServiceOptions extends MQTT.IClientOptions {
export interface MqttServiceOptions extends IClientOptions {
/** wether a new connection should be created
* on creating an instance of the service */
connectOnCreate?: boolean;
Expand All @@ -19,7 +19,7 @@ export interface MqttServiceOptions extends MQTT.IClientOptions {
protocol?: 'wss' | 'ws';
}

export interface MqttMessage extends MQTT.IPacket {
export interface MqttMessage extends IPacket {
/** the mqtt topic to which this message was published to */
topic: string;
/** the payload */
Expand All @@ -32,11 +32,15 @@ export interface MqttMessage extends MQTT.IPacket {
dup: boolean;
}

export interface PublishOptions extends MQTT.IClientPublishOptions { }
// tslint:disable-next-line:no-empty-interface
export interface PublishOptions extends IClientPublishOptions { }
// tslint:disable-next-line:no-empty-interface
export interface OnConnectEvent extends MqttMessage { }
// tslint:disable-next-line:no-empty-interface
export interface OnErrorEvent extends Error { }
// tslint:disable-next-line:no-empty-interface
export interface OnMessageEvent extends MqttMessage { }
export interface OnSubackEvent {
granted: boolean;
filter: string;
}
}
77 changes: 38 additions & 39 deletions projects/ngx-mqtt/src/lib/mqtt.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
Subject,
Unsubscribable,
using } from 'rxjs';
import { filter, publishReplay, refCount } from 'rxjs/operators';
import { filter as filterOperator, publishReplay, refCount } from 'rxjs/operators';

import { connect, ISubscriptionGrant, MqttClient } from 'mqtt';
const extend = require('extend');
Expand Down Expand Up @@ -46,6 +46,42 @@ export class MqttService {
private _onMessage: EventEmitter<OnMessageEvent> = new EventEmitter<OnMessageEvent>();
private _onSuback: EventEmitter<OnSubackEvent> = new EventEmitter<OnSubackEvent>();

/**
* This static method shall be used to determine whether a MQTT
* topic matches a given filter. The matching rules are specified in the MQTT
* standard documentation and in the library test suite.
*
* @param filter A filter may contain wildcards like '#' and '+'.
* @param topic A topic may not contain wildcards.
* @return true on match and false otherwise.
*/
public static filterMatchesTopic(filter: string, topic: string): boolean {
if (filter[0] === '#' && topic[0] === '$') {
return false;
}
// Preparation: split and reverse on '/'. The JavaScript split function is sane.
const fs = (filter || '').split('/').reverse();
const ts = (topic || '').split('/').reverse();
// This function is tail recursive and compares both arrays one element at a time.
const match = (): boolean => {
// Cutting of the last element of both the filter and the topic using pop().
const f = fs.pop();
const t = ts.pop();
switch (f) {
// In case the filter level is '#', this is a match no matter whether
// the topic is undefined on this level or not ('#' matches parent element as well!).
case '#': return true;
// In case the filter level is '+', we shall dive into the recursion only if t is not undefined.
case '+': return t ? match() : false;
// In all other cases the filter level must match the topic level,
// both must be defined and the filter tail must match the topic
// tail (which is determined by the recursive call of match()).
default: return f === t && (f === undefined ? true : match());
}
};
return match();
}

/**
* The constructor needs [connection options]{@link MqttServiceOptions} regarding the broker and some
* options to configure behavior of this service, like if the connection to the broker
Expand Down Expand Up @@ -154,7 +190,7 @@ export class MqttService {
// `observe` gets actually subscribed.
(subscription: Unsubscribable) => merge(rejected, this.messages))
.pipe(
filter((msg: MqttMessage) => MqttService.filterMatchesTopic(filterString, msg.topic)),
filterOperator((msg: MqttMessage) => MqttService.filterMatchesTopic(filterString, msg.topic)),
publishReplay(1),
refCount()
);
Expand Down Expand Up @@ -205,43 +241,6 @@ export class MqttService {
});
}

/**
* This static method shall be used to determine whether a MQTT
* topic matches a given filter. The matching rules are specified in the MQTT
* standard documentation and in the library test suite.
*
* @param filter A filter may contain wildcards like '#' and '+'.
* @param topic A topic may not contain wildcards.
* @return true on match and false otherwise.
*/
public static filterMatchesTopic(filter: string, topic: string): boolean {
if (filter[0] === '#' && topic[0] === '$') {
return false;
}
// Preparation: split and reverse on '/'. The JavaScript split function is sane.
const fs = (filter || '').split('/').reverse();
const ts = (topic || '').split('/').reverse();
// This function is tail recursive and compares both arrays one element at a time.
const match = (): boolean => {
// Cutting of the last element of both the filter and the topic using pop().
const f = fs.pop();
const t = ts.pop();
switch (f) {
// In case the filter level is '#', this is a match no matter whether
// the topic is undefined on this level or not ('#' matches parent element as well!).
case '#': return true;
// In case the filter level is '+', we shall dive into the recursion only if t is not undefined.
case '+': return t ? match() : false;
// In all other cases the filter level must match the topic level,
// both must be defined and the filter tail must match the topic
// tail (which is determined by the recursive call of match()).
default: return f === t && (f === undefined ? true : match());
}
};
return match();
}


/** An EventEmitter to listen to close messages */
public get onClose(): EventEmitter<void> {
return this._onClose;
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"strict": true,
"target": "es5",
"typeRoots": [
"node_modules/@types"
Expand Down

0 comments on commit 558585c

Please sign in to comment.