Skip to content

Commit

Permalink
Use eslint, and refactor typings (#596)
Browse files Browse the repository at this point in the history
* Use eslint, and refactor typings

* Fix: broker should be readonly
  • Loading branch information
gnought authored Mar 15, 2021
1 parent 7040587 commit c390099
Show file tree
Hide file tree
Showing 9 changed files with 235 additions and 323 deletions.
148 changes: 6 additions & 142 deletions aedes.d.ts
Original file line number Diff line number Diff line change
@@ -1,144 +1,8 @@
/* eslint no-unused-vars: 0 */
/* eslint no-undef: 0 */
/* eslint space-infix-ops: 0 */
import { Aedes, AedesOptions } from './types/instance'

/// <reference types="node" />
export declare function aedes (options?: AedesOptions): Aedes
export declare function Server (options?: AedesOptions): Aedes

import { IConnackPacket, IConnectPacket, IPingreqPacket, IPublishPacket, IPubrelPacket, ISubscribePacket, ISubscription, IUnsubscribePacket } from 'mqtt-packet'
import { AedesPacket } from 'aedes-packet'
import { Duplex } from 'stream'
import { Socket } from 'net'
import { IncomingMessage } from 'http'
import EventEmitter = NodeJS.EventEmitter

declare function aedes (options?: aedes.AedesOptions): aedes.Aedes

// eslint-disable-next-line no-redeclare
declare namespace aedes {
enum AuthErrorCode {
UNNACCEPTABLE_PROTOCOL = 1,
IDENTIFIER_REJECTED = 2,
SERVER_UNAVAILABLE = 3,
BAD_USERNAME_OR_PASSWORD = 4,
NOT_AUTHORIZED = 5
}

type Connection = Duplex | Socket

type Subscription = ISubscription
type Subscriptions = { subscriptions: Subscription[] }
type SubscribePacket = ISubscribePacket & { cmd: 'subscribe' }
type UnsubscribePacket = IUnsubscribePacket & { cmd: 'unsubscribe' }

type PublishPacket = IPublishPacket & { cmd: 'publish' }
type AedesPublishPacket = PublishPacket & AedesPacket

type ConnectPacket = IConnectPacket & { cmd: 'connect' }
type ConnackPacket = IConnackPacket & { cmd: 'connack' }
type PubrelPacket = IPubrelPacket & { cmd: 'pubrel' }
type PingreqPacket = IPingreqPacket & { cmd: 'pingreq' }

interface Client extends EventEmitter {
id: string
clean: boolean
version: number
conn: Connection
req?: IncomingMessage
connecting: boolean
connected: boolean
closed: boolean

on (event: 'connected', listener: () => void): this
on (event: 'error', listener: (error: Error) => void): this

publish (message: PublishPacket, callback?: (error?: Error) => void): void
subscribe (
subscriptions: Subscriptions | Subscription | Subscription[] | SubscribePacket,
callback?: (error?: Error) => void
): void
unsubscribe (topicObjects: Subscriptions | Subscription | Subscription[] | UnsubscribePacket, callback?: (error?: Error) => void): void
close (callback?: () => void): void
emptyOutgoingQueue (callback?: () => void): void
}

type PreConnectHandler = (client: Client, packet: IConnectPacket, callback: (error: Error | null, success: boolean) => void) => void

type AuthenticateError = Error & { returnCode: AuthErrorCode }

type AuthenticateHandler = (
client: Client,
username: string,
password: Buffer,
done: (error: AuthenticateError | null, success: boolean | null) => void
) => void

type AuthorizePublishHandler = (client: Client, packet: PublishPacket, callback: (error?: Error | null) => void) => void

type AuthorizeSubscribeHandler = (client: Client, subscription: Subscription, callback: (error: Error | null, subscription?: Subscription | null) => void) => void

type AuthorizeForwardHandler = (client: Client, packet: AedesPublishPacket) => AedesPublishPacket | null | void

type PublishedHandler = (packet: AedesPublishPacket, client: Client, callback: (error?: Error | null) => void) => void

type LastHearthbeatTimestamp = Date;

interface Brokers {
[brokerId: string]: LastHearthbeatTimestamp;
}

interface AedesOptions {
mq?: any
id?: string
persistence?: any
concurrency?: number
heartbeatInterval?: number
connectTimeout?: number
preConnect?: PreConnectHandler
authenticate?: AuthenticateHandler
authorizePublish?: AuthorizePublishHandler
authorizeSubscribe?: AuthorizeSubscribeHandler
authorizeForward?: AuthorizeForwardHandler
published?: PublishedHandler
queueLimit?: number
maxClientsIdLength?: number
}

interface Aedes extends EventEmitter {
id: string
connectedClients: number
closed: boolean
brokers: Brokers

handle: (stream: Connection) => Client

on (event: 'closed', listener: () => void): this
on (event: 'client' | 'clientReady' | 'clientDisconnect' | 'keepaliveTimeout', listener: (client: Client) => void): this
on (event: 'clientError' | 'connectionError', listener: (client: Client, error: Error) => void): this
on (event: 'connackSent', listener: (packet: ConnackPacket, client: Client) => void): this
on (event: 'ping', listener: (packet: PingreqPacket, client: Client) => void): this
on (event: 'publish', listener: (packet: AedesPublishPacket, client: Client) => void): this
on (event: 'ack', listener: (packet: PublishPacket | PubrelPacket, client: Client) => void): this
on (event: 'subscribe', listener: (subscriptions: Subscription[], client: Client) => void): this
on (event: 'unsubscribe', listener: (unsubscriptions: string[], client: Client) => void): this

publish (
packet: PublishPacket,
callback: (error?: Error) => void
): void
subscribe (
topic: string,
deliverfunc: (packet: AedesPublishPacket, callback: () => void) => void,
callback: () => void
): void
unsubscribe (
topic: string,
deliverfunc: (packet: AedesPublishPacket, callback: () => void) => void,
callback: () => void
): void
close (callback?: () => void): void
}

function Server (options?: aedes.AedesOptions): aedes.Aedes
}

export = aedes
export * from './types/instance'
export * from './types/client'
export default aedes
41 changes: 23 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@
"main": "aedes.js",
"types": "aedes.d.ts",
"scripts": {
"lint-fix": "standard --fix",
"lint": "npm run lint:standard && npm run lint:typescript && npm run lint:markdown",
"lint:fix": "standard --fix",
"lint:standard": "standard --verbose | snazzy",
"lint:typescript": "standard --parser @typescript-eslint/parser --plugin @typescript-eslint/eslint-plugin test/types/*.ts aedes.d.ts",
"lint:typescript": "eslint -c types/.eslintrc.json aedes.d.ts types/**/*.ts test/types/**/*.test-d.ts",
"lint:markdown": "markdownlint docs/*.md README.md",
"test": "npm run lint && npm run unit && npm run test:typescript",
"test:ci": "npm run lint && npm run unit -- --cov --coverage-report=lcovonly && npm run test:typescript",
"test:report": "npm run lint && npm run unit:report && npm run test:typescript",
"test:typescript": "tsd",
"unit": "tap --no-esm -J test/*.js",
"unit:report": "tap --no-esm -J test/*.js --cov --coverage-report=html --coverage-report=cobertura | tee out.tap",
"typescript": "tsc --project ./test/types/tsconfig.json",
"test:report": "npm run lint && npm run unit:report && npm run typescript",
"test": "npm run lint && npm run unit && npm run typescript && tsd",
"test:types": "tsd",
"test:ci": "npm run lint && npm run unit -- --cov --coverage-report=lcovonly && npm run typescript",
"license-checker": "license-checker --production --onlyAllow=\"MIT;ISC;BSD-3-Clause;BSD-2-Clause\"",
"release": "read -p 'GITHUB_TOKEN: ' GITHUB_TOKEN && export GITHUB_TOKEN=$GITHUB_TOKEN && release-it --disable-metrics"
},
Expand All @@ -42,6 +41,12 @@
"tsd": {
"directory": "test/types"
},
"standard": {
"ignore": [
"types/*",
"test/types/*"
]
},
"repository": {
"type": "git",
"url": "https://github.com/moscajs/aedes.git"
Expand Down Expand Up @@ -91,40 +96,40 @@
],
"license": "MIT",
"devDependencies": {
"@sinonjs/fake-timers": "^7.0.0",
"@types/node": "^14.14.10",
"@typescript-eslint/eslint-plugin": "^4.9.0",
"@typescript-eslint/parser": "^4.9.0",
"@sinonjs/fake-timers": "^7.0.2",
"@types/node": "^14.14.34",
"@typescript-eslint/eslint-plugin": "^4.17.0",
"@typescript-eslint/parser": "^4.17.0",
"concat-stream": "^2.0.0",
"duplexify": "^4.1.1",
"license-checker": "^25.0.1",
"markdownlint-cli": "^0.27.1",
"mqtt": "^4.2.6",
"mqtt-connection": "^4.0.0",
"mqtt-connection": "^4.1.0",
"pre-commit": "^1.2.2",
"proxyquire": "^2.1.3",
"release-it": "^14.2.2",
"release-it": "^14.4.1",
"snazzy": "^9.0.0",
"standard": "^16.0.3",
"tap": "^14.11.0",
"tsd": "^0.14.0",
"typescript": "^4.1.2",
"typescript": "^4.2.3",
"websocket-stream": "^5.5.2"
},
"dependencies": {
"aedes-packet": "^2.3.1",
"aedes-persistence": "^8.1.1",
"aedes-persistence": "^8.1.3",
"bulk-write-stream": "^2.0.1",
"end-of-stream": "^1.4.4",
"fastfall": "^1.5.1",
"fastparallel": "^2.4.0",
"fastseries": "^2.0.0",
"hyperid": "^2.0.5",
"mqemitter": "^4.4.0",
"hyperid": "^2.1.0",
"mqemitter": "^4.4.1",
"mqtt-packet": "^6.9.0",
"readable-stream": "^3.6.0",
"retimer": "^3.0.0",
"reusify": "^1.0.4",
"uuid": "^8.3.1"
"uuid": "^8.3.2"
}
}
39 changes: 22 additions & 17 deletions test/types/aedes.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,23 @@
/* eslint no-unused-vars: 0 */
/* eslint no-undef: 0 */

import { expectType } from 'tsd'
import { Socket } from 'net'
import type {
Aedes,
Brokers,
Client,
Connection,
ConnackPacket,
AuthenticateError,
AedesPublishPacket,
PublishPacket,
Subscription,
SubscribePacket,
UnsubscribePacket
Client,
Connection
} from '../../aedes'
import { Server } from '../../aedes'
import type { Packet } from 'mqtt-packet'
import { Socket } from 'net'
import type { AedesPublishPacket, ConnackPacket, ConnectPacket, PingreqPacket, PublishPacket, PubrelPacket, Subscription, SubscribePacket, UnsubscribePacket } from '../../types/packet'

// Aedes server
const broker = Server({
id: 'aedes',
concurrency: 100,
heartbeatInterval: 60000,
connectTimeout: 30000,
id: 'aedes',
preConnect: (client: Client, packet: Packet, callback) => {
maxClientsIdLength: 23,
preConnect: (client: Client, packet: ConnectPacket, callback) => {
if (client.req) {
callback(new Error('not websocket stream'), false)
}
Expand All @@ -35,7 +27,7 @@ const broker = Server({
callback(new Error('connection error'), false)
}
},
authenticate: (client: Client, username: string, password: Buffer, callback) => {
authenticate: (client: Client, username: Readonly<string>, password: Readonly<Buffer>, callback) => {
if (username === 'test' && password === Buffer.from('test') && client.version === 4) {
callback(null, true)
} else {
Expand Down Expand Up @@ -81,17 +73,30 @@ const broker = Server({
}

return packet
},
published: (packet: AedesPublishPacket, client: Client, callback) => {
callback(null)
callback(new Error())
}
})

expectType<Aedes>(broker)

expectType<Brokers>(broker.brokers)
expectType<Readonly<Brokers>>(broker.brokers)

expectType<Aedes>(broker.on('closed', () => {}))
expectType<Aedes>(broker.on('client', (client: Client) => {}))
expectType<Aedes>(broker.on('clientReady', (client: Client) => {}))
expectType<Aedes>(broker.on('clientDisconnect', (client: Client) => {}))
expectType<Aedes>(broker.on('keepaliveTimeout', (client: Client) => {}))
expectType<Aedes>(broker.on('clientError', (client: Client, error: Error) => {}))
expectType<Aedes>(broker.on('connectionError', (client: Client, error: Error) => {}))
expectType<Aedes>(broker.on('connackSent', (packet: ConnackPacket, client: Client) => {}))
expectType<Aedes>(broker.on('ping', (packet: PingreqPacket, client: Client) => {}))
expectType<Aedes>(broker.on('publish', (packet: AedesPublishPacket, client: Client) => {}))
expectType<Aedes>(broker.on('ack', (packet: PublishPacket | PubrelPacket, client: Client) => {}))
expectType<Aedes>(broker.on('subscribe', (subscriptions: Subscription[], client: Client) => {}))
expectType<Aedes>(broker.on('unsubscribe', (unsubscriptions: string[], client: Client) => {}))

expectType<void>(broker.publish(
{} as PublishPacket,
Expand Down
Loading

0 comments on commit c390099

Please sign in to comment.