From ffbf344eb06f93ebf4af722639f897d584807a8b Mon Sep 17 00:00:00 2001 From: AJ Livingston Date: Sat, 14 Apr 2018 15:18:11 -0400 Subject: [PATCH] Add typings for express-ws (#24984) * Add types for express-ws * strictFunctionTypes=true * dtslint compliant * union types for application and router * allow https server * applyTo accepts object * fix lint error * applyTo accepts router-like obj * websocket method returns this --- types/express-ws/express-ws-tests.ts | 72 ++++++++++++++++++++++++++++ types/express-ws/index.d.ts | 47 ++++++++++++++++++ types/express-ws/tsconfig.json | 23 +++++++++ types/express-ws/tslint.json | 1 + 4 files changed, 143 insertions(+) create mode 100644 types/express-ws/express-ws-tests.ts create mode 100644 types/express-ws/index.d.ts create mode 100644 types/express-ws/tsconfig.json create mode 100644 types/express-ws/tslint.json diff --git a/types/express-ws/express-ws-tests.ts b/types/express-ws/express-ws-tests.ts new file mode 100644 index 0000000000..a37f315dfb --- /dev/null +++ b/types/express-ws/express-ws-tests.ts @@ -0,0 +1,72 @@ +import http = require('http'); +import https = require('https'); +import express = require('express'); +import expressWs = require('express-ws'); + +const dummyApp = express(); +const httpServer = http.createServer(dummyApp); +const httpsServer = https.createServer({}, dummyApp); + +expressWs(dummyApp); // optional server argument +expressWs(dummyApp, httpsServer); // https server allowed +expressWs(dummyApp, httpServer, { + leaveRouterUntouched: false, + // ws server options + wsOptions: { + clientTracking: true + } +}); + +const { app, getWss, applyTo } = expressWs(express()); + +/** + * applyTo accepts router object + */ +applyTo(express.Router()); + +/** + * applyTo accepts router-like objects + */ +applyTo({ + get() { return this; } +}); + +/** + * getWss function returns ws server + */ +getWss().clients.forEach(ws => { + if (ws.readyState !== ws.OPEN) { + ws.terminate(); + return; + } + ws.ping(); +}); + +/** + * ws method is added to express app instance + */ +app.ws('/', (ws, req) => { + ws.on('message', msg => { + console.log(msg); + }); +}); + +/** + * ws method is added to express.Router prototype + */ +const router = express.Router(); + +router.ws( + '/:id', + (ws, req, next) => { next(); }, + (ws, req, next) => { + ws.send(req.params.id); + + ws.on('close', (code, reason) => { + console.log('code:', code); + console.log('reason:', reason); + }); + } +); + +app.use(router); diff --git a/types/express-ws/index.d.ts b/types/express-ws/index.d.ts new file mode 100644 index 0000000000..81cf85c6d3 --- /dev/null +++ b/types/express-ws/index.d.ts @@ -0,0 +1,47 @@ +// Type definitions for express-ws 3.0 +// Project: https://github.com/HenningM/express-ws +// Definitions by: AJ Livingston +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.3 + +import * as core from 'express-serve-static-core'; +import * as express from 'express'; +import * as http from 'http'; +import * as https from 'https'; +import * as ws from 'ws'; + +declare module 'express' { + function Router(options?: RouterOptions): expressWs.Router; +} + +declare function expressWs(app: express.Application, server?: http.Server | https.Server, options?: expressWs.Options): expressWs.Instance; +declare namespace expressWs { + type Application = express.Application & WithWebsocketMethod; + type Router = express.Router & WithWebsocketMethod; + + interface Options { + leaveRouterUntouched?: boolean; + wsOptions?: ws.ServerOptions; + } + + interface RouterLike { + get: express.IRouterMatcher; + [key: string]: any; + [key: number]: any; + } + + interface Instance { + app: Application; + applyTo(target: RouterLike): void; + getWss(): ws.Server; + } + + type WebsocketRequestHandler = (ws: ws, req: express.Request, next: express.NextFunction) => void; + type WebsocketMethod = (route: core.PathParams, ...middlewares: WebsocketRequestHandler[]) => T; + + interface WithWebsocketMethod { + ws: WebsocketMethod; + } +} + +export = expressWs; diff --git a/types/express-ws/tsconfig.json b/types/express-ws/tsconfig.json new file mode 100644 index 0000000000..e2d5677145 --- /dev/null +++ b/types/express-ws/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "express-ws-tests.ts" + ] +} diff --git a/types/express-ws/tslint.json b/types/express-ws/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/express-ws/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }