diff --git a/.gitignore b/.gitignore index 93f136199..fef838544 100755 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules npm-debug.log +build/ diff --git a/lib/engine.io.js b/lib/engine.io.js deleted file mode 100644 index 43f7c371b..000000000 --- a/lib/engine.io.js +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Module dependencies. - */ - -const http = require("http"); -const Server = require("./server"); - -/** - * Invoking the library as a function delegates to attach if the first argument - * is an `http.Server`. - * - * If there are no arguments or the first argument is an options object, then - * a new Server instance is returned. - * - * @param {http.Server} server (if specified, will be attached to by the new Server instance) - * @param {Object} options - * @return {Server} engine server - * @api public - */ - -exports = module.exports = function() { - // backwards compatible use as `.attach` - // if first argument is an http server - if (arguments.length && arguments[0] instanceof http.Server) { - return attach.apply(this, arguments); - } - - // if first argument is not an http server, then just make a regular eio server - return new Server(...arguments); -}; - -/** - * Protocol revision number. - * - * @api public - */ - -exports.protocol = 1; - -/** - * Expose Server constructor. - * - * @api public - */ - -exports.Server = Server; - -/** - * Expose Socket constructor. - * - * @api public - */ - -exports.Socket = require("./socket"); - -/** - * Expose Transport constructor. - * - * @api public - */ - -exports.Transport = require("./transport"); - -/** - * Expose mutable list of available transports. - * - * @api public - */ - -exports.transports = require("./transports"); - -/** - * Exports parser. - * - * @api public - */ - -exports.parser = require("engine.io-parser"); - -/** - * Creates an http.Server exclusively used for WS upgrades. - * - * @param {Number} port - * @param {Function} callback - * @param {Object} options - * @return {Server} websocket.io server - * @api public - */ - -exports.listen = listen; - -function listen(port, options, fn) { - if ("function" === typeof options) { - fn = options; - options = {}; - } - - const server = http.createServer(function(req, res) { - res.writeHead(501); - res.end("Not Implemented"); - }); - - // create engine server - const engine = exports.attach(server, options); - engine.httpServer = server; - - server.listen(port, fn); - - return engine; -} - -/** - * Captures upgrade requests for a http.Server. - * - * @param {http.Server} server - * @param {Object} options - * @return {Server} engine server - * @api public - */ - -exports.attach = attach; - -function attach(server, options) { - const engine = new Server(options); - engine.attach(server, options); - return engine; -} diff --git a/lib/engine.io.ts b/lib/engine.io.ts new file mode 100644 index 000000000..71323962f --- /dev/null +++ b/lib/engine.io.ts @@ -0,0 +1,55 @@ +import { createServer } from "http"; +import { Server, AttachOptions, ServerOptions } from "./server"; +import transports from "./transports/index"; +import * as parser from "engine.io-parser"; + +export { Server, transports, listen, attach, parser }; +export { AttachOptions, ServerOptions } from "./server"; +export { Socket } from "./socket"; +export { Transport } from "./transport"; +export const protocol = parser.protocol; + +/** + * Creates an http.Server exclusively used for WS upgrades. + * + * @param {Number} port + * @param {Function} callback + * @param {Object} options + * @return {Server} websocket.io server + * @api public + */ + +function listen(port, options: AttachOptions & ServerOptions, fn) { + if ("function" === typeof options) { + fn = options; + options = {}; + } + + const server = createServer(function(req, res) { + res.writeHead(501); + res.end("Not Implemented"); + }); + + // create engine server + const engine = attach(server, options); + engine.httpServer = server; + + server.listen(port, fn); + + return engine; +} + +/** + * Captures upgrade requests for a http.Server. + * + * @param {http.Server} server + * @param {Object} options + * @return {Server} engine server + * @api public + */ + +function attach(server, options: AttachOptions & ServerOptions) { + const engine = new Server(options); + engine.attach(server, options); + return engine; +} diff --git a/lib/parser-v3/index.js b/lib/parser-v3/index.ts similarity index 89% rename from lib/parser-v3/index.js rename to lib/parser-v3/index.ts index bd5d56baa..6949f1875 100644 --- a/lib/parser-v3/index.js +++ b/lib/parser-v3/index.ts @@ -9,7 +9,7 @@ var utf8 = require('./utf8'); /** * Current protocol version. */ -exports.protocol = 3; +export const protocol = 3; const hasBinary = (packets) => { for (const packet of packets) { @@ -24,7 +24,7 @@ const hasBinary = (packets) => { * Packet types. */ -var packets = exports.packets = { +export const packets = { open: 0 // non-ws , close: 1 // non-ws , ping: 2 @@ -60,7 +60,7 @@ const EMPTY_BUFFER = Buffer.concat([]); * @api private */ -exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) { +export function encodePacket (packet, supportsBinary, utf8encode, callback) { if (typeof supportsBinary === 'function') { callback = supportsBinary; supportsBinary = null; @@ -94,7 +94,7 @@ exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) { function encodeBuffer(packet, supportsBinary, callback) { if (!supportsBinary) { - return exports.encodeBase64Packet(packet, callback); + return encodeBase64Packet(packet, callback); } var data = packet.data; @@ -110,7 +110,7 @@ function encodeBuffer(packet, supportsBinary, callback) { * @return {String} base64 encoded message */ -exports.encodeBase64Packet = function(packet, callback){ +export function encodeBase64Packet (packet, callback){ var data = Buffer.isBuffer(packet.data) ? packet.data : arrayBufferToBuffer(packet.data); var message = 'b' + packets[packet.type]; message += data.toString('base64'); @@ -124,7 +124,7 @@ exports.encodeBase64Packet = function(packet, callback){ * @api private */ -exports.decodePacket = function (data, binaryType, utf8decode) { +export function decodePacket (data, binaryType, utf8decode) { if (data === undefined) { return err; } @@ -137,7 +137,7 @@ exports.decodePacket = function (data, binaryType, utf8decode) { type = data.charAt(0); if (type === 'b') { - return exports.decodeBase64Packet(data.substr(1), binaryType); + return decodeBase64Packet(data.substr(1), binaryType); } if (utf8decode) { @@ -189,7 +189,7 @@ function tryDecode(data) { * @return {Object} with `type` and `data` (if any) */ -exports.decodeBase64Packet = function(msg, binaryType) { +export function decodeBase64Packet (msg, binaryType) { var type = packetslist[msg.charAt(0)]; var data = Buffer.from(msg.substr(1), 'base64'); if (binaryType === 'arraybuffer') { @@ -197,6 +197,7 @@ exports.decodeBase64Packet = function(msg, binaryType) { for (var i = 0; i < abv.length; i++){ abv[i] = data[i]; } + // @ts-ignore data = abv.buffer; } return { type: type, data: data }; @@ -218,14 +219,14 @@ exports.decodeBase64Packet = function(msg, binaryType) { * @api private */ -exports.encodePayload = function (packets, supportsBinary, callback) { +export function encodePayload (packets, supportsBinary, callback) { if (typeof supportsBinary === 'function') { callback = supportsBinary; supportsBinary = null; } if (supportsBinary && hasBinary(packets)) { - return exports.encodePayloadAsBinary(packets, callback); + return encodePayloadAsBinary(packets, callback); } if (!packets.length) { @@ -233,7 +234,7 @@ exports.encodePayload = function (packets, supportsBinary, callback) { } function encodeOne(packet, doneCallback) { - exports.encodePacket(packet, supportsBinary, false, function(message) { + encodePacket(packet, supportsBinary, false, function(message) { doneCallback(null, setLengthHeader(message)); }); } @@ -273,9 +274,9 @@ function map(ary, each, done) { * @api public */ -exports.decodePayload = function (data, binaryType, callback) { +export function decodePayload (data, binaryType, callback) { if (typeof data !== 'string') { - return exports.decodePayloadAsBinary(data, binaryType, callback); + return decodePayloadAsBinary(data, binaryType, callback); } if (typeof binaryType === 'function') { @@ -298,6 +299,7 @@ exports.decodePayload = function (data, binaryType, callback) { continue; } + // @ts-ignore if (length === '' || (length != (n = Number(length)))) { // parser error - ignoring payload return callback(err, 0, 1); @@ -311,7 +313,7 @@ exports.decodePayload = function (data, binaryType, callback) { } if (msg.length) { - packet = exports.decodePacket(msg, binaryType, false); + packet = decodePacket(msg, binaryType, false); if (err.type === packet.type && err.data === packet.data) { // parser error in individual packet - ignoring payload @@ -393,7 +395,7 @@ function arrayBufferToBuffer(data) { * @api private */ -exports.encodePayloadAsBinary = function (packets, callback) { +export function encodePayloadAsBinary (packets, callback) { if (!packets.length) { return callback(EMPTY_BUFFER); } @@ -430,7 +432,7 @@ function encodeOneBinaryPacket(p, doneCallback) { doneCallback(null, Buffer.concat([sizeBuffer, packet])); } - exports.encodePacket(p, true, true, onBinaryPacketEncode); + encodePacket(p, true, true, onBinaryPacketEncode); } @@ -444,7 +446,7 @@ function encodeOneBinaryPacket(p, doneCallback) { * @api public */ -exports.decodePayloadAsBinary = function (data, binaryType, callback) { +export function decodePayloadAsBinary (data, binaryType, callback) { if (typeof binaryType === 'function') { callback = binaryType; binaryType = null; @@ -478,6 +480,6 @@ exports.decodePayloadAsBinary = function (data, binaryType, callback) { var total = buffers.length; for (i = 0; i < total; i++) { var buffer = buffers[i]; - callback(exports.decodePacket(buffer, binaryType, true), i, total); + callback(decodePacket(buffer, binaryType, true), i, total); } }; diff --git a/lib/parser-v3/utf8.js b/lib/parser-v3/utf8.ts similarity index 99% rename from lib/parser-v3/utf8.js rename to lib/parser-v3/utf8.ts index b878740ff..9a9decbd3 100644 --- a/lib/parser-v3/utf8.js +++ b/lib/parser-v3/utf8.ts @@ -203,7 +203,7 @@ function utf8decode(byteString, opts) { return ucs2encode(codePoints); } -module.exports = { +export default { version: '2.1.2', encode: utf8encode, decode: utf8decode diff --git a/lib/server.js b/lib/server.ts similarity index 77% rename from lib/server.js rename to lib/server.ts index d3087ab8b..bd69d6ec0 100644 --- a/lib/server.js +++ b/lib/server.ts @@ -1,22 +1,135 @@ -const qs = require("querystring"); -const parse = require("url").parse; -const base64id = require("base64id"); -const transports = require("./transports"); -const EventEmitter = require("events").EventEmitter; -const Socket = require("./socket"); -const debug = require("debug")("engine"); -const cookieMod = require("cookie"); - -const DEFAULT_WS_ENGINE = require("ws").Server; - -class Server extends EventEmitter { +import * as qs from "querystring"; +import { parse } from "url"; +import * as base64id from "base64id"; +import transports from "./transports"; +import { EventEmitter } from "events"; +import { Socket } from "./socket"; +import debugModule from "debug"; +import { serialize } from "cookie"; +import { Server as DEFAULT_WS_ENGINE } from "ws"; +import { IncomingMessage, Server as HttpServer } from "http"; +import { CookieSerializeOptions } from "cookie"; +import { CorsOptions } from "cors"; + +const debug = debugModule("engine"); + +type Transport = "polling" | "websocket"; + +export interface AttachOptions { + /** + * name of the path to capture + * @default "/engine.io" + */ + path?: string; + /** + * destroy unhandled upgrade requests + * @default true + */ + destroyUpgrade?: boolean; + /** + * milliseconds after which unhandled requests are ended + * @default 1000 + */ + destroyUpgradeTimeout?: number; +} + +export interface ServerOptions { + /** + * how many ms without a pong packet to consider the connection closed + * @default 20000 + */ + pingTimeout?: number; + /** + * how many ms before sending a new ping packet + * @default 25000 + */ + pingInterval?: number; + /** + * how many ms before an uncompleted transport upgrade is cancelled + * @default 10000 + */ + upgradeTimeout?: number; + /** + * how many bytes or characters a message can be, before closing the session (to avoid DoS). + * @default 1e5 (100 KB) + */ + maxHttpBufferSize?: number; + /** + * A function that receives a given handshake or upgrade request as its first parameter, + * and can decide whether to continue or not. The second argument is a function that needs + * to be called with the decided information: fn(err, success), where success is a boolean + * value where false means that the request is rejected, and err is an error code. + */ + allowRequest?: ( + req: IncomingMessage, + fn: (err: string | null | undefined, success: boolean) => void + ) => void; + /** + * the low-level transports that are enabled + * @default ["polling", "websocket"] + */ + transports?: Transport[]; + /** + * whether to allow transport upgrades + * @default true + */ + allowUpgrades?: boolean; + /** + * parameters of the WebSocket permessage-deflate extension (see ws module api docs). Set to false to disable. + * @default false + */ + perMessageDeflate?: boolean | object; + /** + * parameters of the http compression for the polling transports (see zlib api docs). Set to false to disable. + * @default true + */ + httpCompression?: boolean | object; + /** + * what WebSocket server implementation to use. Specified module must + * conform to the ws interface (see ws module api docs). + * An alternative c++ addon is also available by installing eiows module. + * + * @default `require("ws").Server` + */ + wsEngine?: any; + /** + * an optional packet which will be concatenated to the handshake packet emitted by Engine.IO. + */ + initialPacket?: any; + /** + * configuration of the cookie that contains the client sid to send as part of handshake response headers. This cookie + * might be used for sticky-session. Defaults to not sending any cookie. + * @default false + */ + cookie?: (CookieSerializeOptions & { name: string }) | boolean; + /** + * the options that will be forwarded to the cors module + */ + cors?: CorsOptions; + /** + * whether to enable compatibility with Socket.IO v2 clients + * @default false + */ + allowEIO3?: boolean; +} + +export class Server extends EventEmitter { + public opts: ServerOptions; + public httpServer?: HttpServer; + + private clients: any; + private clientsCount: number; + private ws: any; + private corsMiddleware: Function; + private perMessageDeflate: any; + /** * Server constructor. * - * @param {Object} options + * @param {Object} opts - options * @api public */ - constructor(opts = {}) { + constructor(opts: ServerOptions = {}) { super(); this.clients = {}; @@ -45,6 +158,7 @@ class Server extends EventEmitter { { name: "io", path: "/", + // @ts-ignore httpOnly: opts.cookie.path !== false, sameSite: "lax" }, @@ -73,7 +187,7 @@ class Server extends EventEmitter { * * @api private */ - init() { + private init() { if (!~this.opts.transports.indexOf("websocket")) return; if (this.ws) this.ws.close(); @@ -111,7 +225,7 @@ class Server extends EventEmitter { * @return {Array} * @api public */ - upgrades(transport) { + public upgrades(transport) { if (!this.opts.allowUpgrades) return []; return transports[transport].upgradesTo || []; } @@ -123,7 +237,7 @@ class Server extends EventEmitter { * @return {Boolean} whether the request is valid * @api private */ - verify(req, upgrade, fn) { + private verify(req, upgrade, fn) { // transport check const transport = req._query.transport; if (!~this.opts.transports.indexOf(transport)) { @@ -189,7 +303,7 @@ class Server extends EventEmitter { * * @api private */ - prepare(req) { + private prepare(req) { // try to leverage pre-existing `req._query` (e.g: from connect) if (!req._query) { req._query = ~req.url.indexOf("?") ? qs.parse(parse(req.url).query) : {}; @@ -201,7 +315,7 @@ class Server extends EventEmitter { * * @api public */ - close() { + public close() { debug("closing all open clients"); for (let i in this.clients) { if (this.clients.hasOwnProperty(i)) { @@ -223,7 +337,7 @@ class Server extends EventEmitter { * @param {http.ServerResponse|http.OutgoingMessage} response * @api public */ - handleRequest(req, res) { + public handleRequest(req, res) { debug('handling "%s" http request "%s"', req.method, req.url); this.prepare(req); req.res = res; @@ -266,7 +380,7 @@ class Server extends EventEmitter { * @param {Object} request object * @api public */ - generateId(req) { + public generateId(req) { return base64id.generateId(); } @@ -279,7 +393,7 @@ class Server extends EventEmitter { * * @api private */ - async handshake(transportName, req, closeConnection) { + private async handshake(transportName, req, closeConnection) { const protocol = req._query.EIO === "4" ? 4 : 3; // 3rd revision by default if (protocol === 3 && !this.opts.allowEIO3) { debug("unsupported protocol version"); @@ -352,7 +466,8 @@ class Server extends EventEmitter { if (isInitialRequest) { if (this.opts.cookie) { headers["Set-Cookie"] = [ - cookieMod.serialize(this.opts.cookie.name, id, this.opts.cookie) + // @ts-ignore + serialize(this.opts.cookie.name, id, this.opts.cookie) ]; } this.emit("initial_headers", headers, req); @@ -378,7 +493,7 @@ class Server extends EventEmitter { * * @api public */ - handleUpgrade(req, socket, upgradeHead) { + public handleUpgrade(req, socket, upgradeHead) { this.prepare(req); this.verify(req, true, (errorCode, errorContext) => { @@ -409,7 +524,7 @@ class Server extends EventEmitter { * @param {ws.Socket} websocket * @api private */ - onWebSocket(req, socket, websocket) { + private onWebSocket(req, socket, websocket) { websocket.on("error", onUpgradeError); if ( @@ -475,7 +590,7 @@ class Server extends EventEmitter { * @param {Object} options * @api public */ - attach(server, options = {}) { + public attach(server, options: AttachOptions = {}) { let path = (options.path || "/engine.io").replace(/\/$/, ""); const destroyUpgradeTimeout = options.destroyUpgradeTimeout || 1000; @@ -525,29 +640,29 @@ class Server extends EventEmitter { }); } } -} -/** - * Protocol errors mappings. - */ + /** + * Protocol errors mappings. + */ -Server.errors = { - UNKNOWN_TRANSPORT: 0, - UNKNOWN_SID: 1, - BAD_HANDSHAKE_METHOD: 2, - BAD_REQUEST: 3, - FORBIDDEN: 4, - UNSUPPORTED_PROTOCOL_VERSION: 5 -}; - -Server.errorMessages = { - 0: "Transport unknown", - 1: "Session ID unknown", - 2: "Bad handshake method", - 3: "Bad request", - 4: "Forbidden", - 5: "Unsupported protocol version" -}; + static errors = { + UNKNOWN_TRANSPORT: 0, + UNKNOWN_SID: 1, + BAD_HANDSHAKE_METHOD: 2, + BAD_REQUEST: 3, + FORBIDDEN: 4, + UNSUPPORTED_PROTOCOL_VERSION: 5 + }; + + static errorMessages = { + 0: "Transport unknown", + 1: "Session ID unknown", + 2: "Bad handshake method", + 3: "Bad request", + 4: "Forbidden", + 5: "Unsupported protocol version" + }; +} /** * Close the HTTP long-polling request @@ -585,7 +700,11 @@ function abortRequest(res, errorCode, errorContext) { * @api private */ -function abortUpgrade(socket, errorCode, errorContext = {}) { +function abortUpgrade( + socket, + errorCode, + errorContext: { message?: string } = {} +) { socket.on("error", () => { debug("ignoring error from closed connection"); }); @@ -606,8 +725,6 @@ function abortUpgrade(socket, errorCode, errorContext = {}) { socket.destroy(); } -module.exports = Server; - /* eslint-disable */ /** diff --git a/lib/socket.js b/lib/socket.ts similarity index 89% rename from lib/socket.js rename to lib/socket.ts index 733793416..f9293213c 100644 --- a/lib/socket.js +++ b/lib/socket.ts @@ -1,7 +1,33 @@ -const EventEmitter = require("events"); -const debug = require("debug")("engine:socket"); +import { EventEmitter } from "events"; +import debugModule from "debug"; +import { IncomingMessage } from "http"; +import { Transport } from "./transport"; +import { Server } from "./server"; + +const debug = debugModule("engine:socket"); + +export class Socket extends EventEmitter { + public readonly protocol: number; + public readonly request: IncomingMessage; + public readonly remoteAddress: string; + + public readyState: string; + public transport: Transport; + + private server: Server; + private upgrading: boolean; + private upgraded: boolean; + private writeBuffer: any[]; + private packetsFn: any[]; + private sentCallbackFn: any[]; + private cleanupFn: any[]; + private checkIntervalTimer; + private upgradeTimeoutTimer; + private pingTimeoutTimer; + private pingIntervalTimer; + + private readonly id: string; -class Socket extends EventEmitter { /** * Client class (abstract). * @@ -42,7 +68,7 @@ class Socket extends EventEmitter { * * @api private */ - onOpen() { + private onOpen() { this.readyState = "open"; // sends an `open` packet @@ -80,7 +106,7 @@ class Socket extends EventEmitter { * @param {Object} packet * @api private */ - onPacket(packet) { + private onPacket(packet) { if ("open" !== this.readyState) { return debug("packet received with closed socket"); } @@ -132,7 +158,7 @@ class Socket extends EventEmitter { * @param {Error} error object * @api private */ - onError(err) { + private onError(err) { debug("transport error"); this.onClose("transport error", err); } @@ -143,7 +169,7 @@ class Socket extends EventEmitter { * * @api private */ - schedulePing() { + private schedulePing() { clearTimeout(this.pingIntervalTimer); this.pingIntervalTimer = setTimeout(() => { debug( @@ -160,7 +186,7 @@ class Socket extends EventEmitter { * * @api private */ - resetPingTimeout(timeout) { + private resetPingTimeout(timeout) { clearTimeout(this.pingTimeoutTimer); this.pingTimeoutTimer = setTimeout(() => { if (this.readyState === "closed") return; @@ -174,7 +200,7 @@ class Socket extends EventEmitter { * @param {Transport} transport * @api private */ - setTransport(transport) { + private setTransport(transport) { const onError = this.onError.bind(this); const onPacket = this.onPacket.bind(this); const flush = this.flush.bind(this); @@ -202,7 +228,7 @@ class Socket extends EventEmitter { * @param {Transport} transport * @api private */ - maybeUpgrade(transport) { + private maybeUpgrade(transport) { debug( 'might upgrade socket transport from "%s" to "%s"', this.transport.name, @@ -296,7 +322,7 @@ class Socket extends EventEmitter { * * @api private */ - clearTransport() { + private clearTransport() { let cleanup; const toCleanUp = this.cleanupFn.length; @@ -322,7 +348,7 @@ class Socket extends EventEmitter { * Possible reasons: `ping timeout`, `client error`, `parse error`, * `transport error`, `server close`, `transport close` */ - onClose(reason, description) { + private onClose(reason: string, description?) { if ("closed" !== this.readyState) { this.readyState = "closed"; @@ -350,7 +376,7 @@ class Socket extends EventEmitter { * * @api private */ - setupSendCallback() { + private setupSendCallback() { // the message was sent successfully, execute the callback const onDrain = () => { if (this.sentCallbackFn.length > 0) { @@ -387,12 +413,12 @@ class Socket extends EventEmitter { * @return {Socket} for chaining * @api public */ - send(data, options, callback) { + public send(data, options, callback?) { this.sendPacket("message", data, options, callback); return this; } - write(data, options, callback) { + public write(data, options, callback?) { this.sendPacket("message", data, options, callback); return this; } @@ -405,7 +431,7 @@ class Socket extends EventEmitter { * @param {Object} options * @api private */ - sendPacket(type, data, options, callback) { + private sendPacket(type, data?, options?, callback?) { if ("function" === typeof options) { callback = options; options = null; @@ -417,7 +443,7 @@ class Socket extends EventEmitter { if ("closing" !== this.readyState && "closed" !== this.readyState) { debug('sending packet "%s" (%s)', type, data); - const packet = { + const packet: any = { type: type, options: options }; @@ -440,7 +466,7 @@ class Socket extends EventEmitter { * * @api private */ - flush() { + private flush() { if ( "closed" !== this.readyState && this.transport.writable && @@ -468,7 +494,7 @@ class Socket extends EventEmitter { * * @api private */ - getAvailableUpgrades() { + private getAvailableUpgrades() { const availableUpgrades = []; const allUpgrades = this.server.upgrades(this.transport.name); let i = 0; @@ -485,11 +511,11 @@ class Socket extends EventEmitter { /** * Closes the socket and underlying transport. * - * @param {Boolean} optional, discard + * @param {Boolean} discard - optional, discard the transport * @return {Socket} for chaining * @api public */ - close(discard) { + public close(discard?: boolean) { if ("open" !== this.readyState) return; this.readyState = "closing"; @@ -508,10 +534,8 @@ class Socket extends EventEmitter { * @param {Boolean} discard * @api private */ - closeTransport(discard) { + private closeTransport(discard) { if (discard) this.transport.discard(); this.transport.close(this.onClose.bind(this, "forced close")); } } - -module.exports = Socket; diff --git a/lib/transport.js b/lib/transport.ts similarity index 62% rename from lib/transport.js rename to lib/transport.ts index 0da3993cb..a82e1b846 100644 --- a/lib/transport.js +++ b/lib/transport.ts @@ -1,7 +1,10 @@ -const EventEmitter = require("events"); -const parser_v4 = require("engine.io-parser"); -const parser_v3 = require("./parser-v3/index"); -const debug = require("debug")("engine:transport"); +import { EventEmitter } from "events"; +import * as parser_v4 from "engine.io-parser"; +import * as parser_v3 from "./parser-v3/index"; +import debugModule from "debug"; +import { IncomingMessage } from "http"; + +const debug = debugModule("engine:transport"); /** * Noop function. @@ -11,7 +14,17 @@ const debug = require("debug")("engine:transport"); function noop() {} -class Transport extends EventEmitter { +export abstract class Transport extends EventEmitter { + public sid: string; + public writable: boolean; + public protocol: number; + + protected readyState: string; + protected discarded: boolean; + protected parser: any; + protected req: IncomingMessage & { cleanup: Function }; + protected supportsBinary: boolean; + /** * Transport constructor. * @@ -39,9 +52,9 @@ class Transport extends EventEmitter { * Called with an incoming HTTP request. * * @param {http.IncomingMessage} request - * @api private + * @api protected */ - onRequest(req) { + protected onRequest(req) { debug("setting request"); this.req = req; } @@ -51,7 +64,7 @@ class Transport extends EventEmitter { * * @api private */ - close(fn) { + close(fn?) { if ("closed" === this.readyState || "closing" === this.readyState) return; this.readyState = "closing"; @@ -63,12 +76,14 @@ class Transport extends EventEmitter { * * @param {String} message error * @param {Object} error description - * @api private + * @api protected */ - onError(msg, desc) { + protected onError(msg: string, desc?) { if (this.listeners("error").length) { const err = new Error(msg); + // @ts-ignore err.type = "TransportError"; + // @ts-ignore err.description = desc; this.emit("error", err); } else { @@ -80,9 +95,9 @@ class Transport extends EventEmitter { * Called with parsed out a packets from the data stream. * * @param {Object} packet - * @api private + * @api protected */ - onPacket(packet) { + protected onPacket(packet) { this.emit("packet", packet); } @@ -90,21 +105,24 @@ class Transport extends EventEmitter { * Called with the encoded packet data. * * @param {String} data - * @api private + * @api protected */ - onData(data) { + protected onData(data) { this.onPacket(this.parser.decodePacket(data)); } /** * Called upon transport close. * - * @api private + * @api protected */ - onClose() { + protected onClose() { this.readyState = "closed"; this.emit("close"); } -} -module.exports = Transport; + abstract get supportsFraming(); + abstract get name(); + abstract send(packets); + abstract doClose(fn?); +} diff --git a/lib/transports/index.js b/lib/transports/index.js deleted file mode 100644 index 98e0ab537..000000000 --- a/lib/transports/index.js +++ /dev/null @@ -1,31 +0,0 @@ -const XHR = require("./polling"); -const JSONP = require("./polling-jsonp"); - -/** - * Export transports. - */ - -module.exports = exports = { - polling: polling, - websocket: require("./websocket") -}; - -/** - * Export upgrades map. - */ - -exports.polling.upgradesTo = ["websocket"]; - -/** - * Polling polymorphic constructor. - * - * @api private - */ - -function polling(req) { - if ("string" === typeof req._query.j) { - return new JSONP(req); - } else { - return new XHR(req); - } -} diff --git a/lib/transports/index.ts b/lib/transports/index.ts new file mode 100644 index 000000000..55065bd66 --- /dev/null +++ b/lib/transports/index.ts @@ -0,0 +1,24 @@ +import { Polling as XHR } from "./polling"; +import { JSONP } from "./polling-jsonp"; +import { WebSocket } from "./websocket"; + +export default { + polling: polling, + websocket: WebSocket +}; + +/** + * Polling polymorphic constructor. + * + * @api private + */ + +function polling(req) { + if ("string" === typeof req._query.j) { + return new JSONP(req); + } else { + return new XHR(req); + } +} + +polling.upgradesTo = ["websocket"]; diff --git a/lib/transports/polling-jsonp.js b/lib/transports/polling-jsonp.ts similarity index 88% rename from lib/transports/polling-jsonp.js rename to lib/transports/polling-jsonp.ts index bb07ce857..b40f935e9 100644 --- a/lib/transports/polling-jsonp.js +++ b/lib/transports/polling-jsonp.ts @@ -1,9 +1,13 @@ -const Polling = require("./polling"); -const qs = require("querystring"); +import { Polling } from "./polling"; +import * as qs from "querystring"; + const rDoubleSlashes = /\\\\n/g; const rSlashes = /(\\)?\\n/g; -class JSONP extends Polling { +export class JSONP extends Polling { + private readonly head: string; + private readonly foot: string; + /** * JSON-P polling transport. * @@ -54,5 +58,3 @@ class JSONP extends Polling { super.doWrite(data, options, callback); } } - -module.exports = JSONP; diff --git a/lib/transports/polling.js b/lib/transports/polling.ts similarity index 92% rename from lib/transports/polling.js rename to lib/transports/polling.ts index f0909d070..c96010f1d 100644 --- a/lib/transports/polling.js +++ b/lib/transports/polling.ts @@ -1,14 +1,27 @@ -const Transport = require("../transport"); -const zlib = require("zlib"); -const accepts = require("accepts"); -const debug = require("debug")("engine:polling"); +import { Transport } from "../transport"; +import { createGzip, createDeflate } from "zlib"; +import * as accepts from "accepts"; +import debugModule from "debug"; +import { IncomingMessage, ServerResponse } from "http"; + +const debug = debugModule("engine:polling"); const compressionMethods = { - gzip: zlib.createGzip, - deflate: zlib.createDeflate + gzip: createGzip, + deflate: createDeflate }; -class Polling extends Transport { +export class Polling extends Transport { + public maxHttpBufferSize: number; + public httpCompression: any; + + private res: ServerResponse; + private dataReq: IncomingMessage; + private dataRes: ServerResponse; + private shouldClose: Function; + + private readonly closeTimeout: number; + /** * HTTP polling constructor. * @@ -18,8 +31,6 @@ class Polling extends Transport { super(req); this.closeTimeout = 30 * 1000; - this.maxHttpBufferSize = null; - this.httpCompression = null; } /** @@ -31,6 +42,10 @@ class Polling extends Transport { return "polling"; } + get supportsFraming() { + return false; + } + /** * Overrides onRequest. * @@ -381,5 +396,3 @@ class Polling extends Transport { return headers; } } - -module.exports = Polling; diff --git a/lib/transports/websocket.js b/lib/transports/websocket.ts similarity index 89% rename from lib/transports/websocket.js rename to lib/transports/websocket.ts index 1daf6caa9..55c286134 100644 --- a/lib/transports/websocket.js +++ b/lib/transports/websocket.ts @@ -1,7 +1,12 @@ -const Transport = require("../transport"); -const debug = require("debug")("engine:ws"); +import { Transport } from "../transport"; +import debugModule from "debug"; + +const debug = debugModule("engine:ws"); + +export class WebSocket extends Transport { + protected perMessageDeflate: any; + private socket: any; -class WebSocket extends Transport { /** * WebSocket transport * @@ -71,7 +76,7 @@ class WebSocket extends Transport { } // always creates a new object since ws modifies it - const opts = {}; + const opts: { compress?: boolean } = {}; if (packet.options) { opts.compress = packet.options.compress; } @@ -111,5 +116,3 @@ class WebSocket extends Transport { fn && fn(); } } - -module.exports = WebSocket; diff --git a/package-lock.json b/package-lock.json index b0082b209..580d081d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -118,6 +118,21 @@ "to-fast-properties": "^2.0.0" } }, + "@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, + "@types/cors": { + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" + }, + "@types/node": { + "version": "16.10.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.3.tgz", + "integrity": "sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ==" + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -127,65 +142,12 @@ "negotiator": "0.6.2" } }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } - }, "after": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", "dev": true }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", - "dev": true - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -195,15 +157,6 @@ "color-convert": "^1.9.0" } }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, "arraybuffer.slice": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", @@ -216,53 +169,6 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, "babel-eslint": { "version": "8.2.6", "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-8.2.6.tgz", @@ -322,27 +228,6 @@ "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", "dev": true }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -354,39 +239,6 @@ "supports-color": "^5.3.0" } }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -435,18 +287,6 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "cookie": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", @@ -473,17 +313,6 @@ "vary": "^1" } }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -492,12 +321,6 @@ "ms": "2.1.2" } }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -510,15 +333,6 @@ "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", "dev": true }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, "eiows": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/eiows/-/eiows-3.3.2.tgz", @@ -610,81 +424,25 @@ } }, "engine.io-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.0.tgz", - "integrity": "sha512-dfV5CyDe0Z5I6L5gyZZXIuWhqtaIrKhHLTfsQpTvDkoQfPPuQe94wkUBCsBe2HOlbNojiDxQRi9RvMNNZRyarw==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", - "dev": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.0.tgz", + "integrity": "sha512-wn6QavHEqXoM+cg+x8uUG7GhxLBCfKEKNEsCNc7V2ugj3gB3lK91l1MuZiy6xFB2V9D1eew0aWkmpiT/aBb/KA==", "requires": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", - "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", - "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" + "base64-arraybuffer": "~1.0.1" }, "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } + "base64-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz", + "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==" } } }, - "eslint-config-prettier": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", - "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", - "dev": true, - "requires": { - "get-stdin": "^6.0.0" - } + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true }, "eslint-scope": { "version": "3.7.1", @@ -702,39 +460,6 @@ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", - "dev": true, - "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, "esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -776,66 +501,6 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, - "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", - "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - } - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } - }, - "flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" - } - }, "form-data": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", @@ -859,18 +524,6 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "dev": true - }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -891,27 +544,12 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "growl": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", "dev": true }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, "has-binary2": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", @@ -947,27 +585,6 @@ "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, "indexof": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", @@ -990,28 +607,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.4", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - } - }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -1021,74 +616,24 @@ "loose-envify": "^1.0.0" } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, - "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -1104,16 +649,6 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -1139,12 +674,6 @@ "mime-db": "1.44.0" } }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -1154,21 +683,6 @@ "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, "mocha": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", @@ -1253,18 +767,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -1284,35 +786,6 @@ "wrappy": "1" } }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, "parseqs": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", @@ -1331,24 +804,6 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, "prettier": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", @@ -1361,18 +816,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, "qs": { "version": "6.9.4", "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", @@ -1394,68 +837,15 @@ "util-deprecate": "~1.0.1" } }, - "regexpp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", - "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", - "dev": true - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - } - }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" } }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true - }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", - "dev": true, - "requires": { - "rx-lite": "*" - } - }, "s": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/s/-/s-0.1.1.tgz", @@ -1468,70 +858,12 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -1541,29 +873,6 @@ "safe-buffer": "~5.1.0" } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - } - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, "superagent": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", @@ -1602,41 +911,6 @@ "has-flag": "^3.0.0" } }, - "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", - "dev": true, - "requires": { - "ajv": "^5.2.3", - "ajv-keywords": "^2.1.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -1649,19 +923,10 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "typescript": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", + "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", "dev": true }, "util-deprecate": { @@ -1675,36 +940,12 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "ws": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", @@ -1716,12 +957,6 @@ "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", "dev": true }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, "yeast": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", diff --git a/package.json b/package.json index 9aaca5c70..9f2e2fa15 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,8 @@ "name": "engine.io", "version": "5.2.0", "description": "The realtime engine behind Socket.IO. Provides the foundation of a bidirectional connection between client and server", - "main": "lib/engine.io.js", + "main": "./build/engine.io.js", + "types": "./build/engine.io.d.ts", "author": "Guillermo Rauch ", "homepage": "https://github.com/socketio/engine.io", "contributors": [ @@ -25,12 +26,15 @@ ], "license": "MIT", "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "2.0.0", "cookie": "~0.4.1", "cors": "~2.8.5", "debug": "~4.3.1", - "engine.io-parser": "~4.0.0", + "engine.io-parser": "~5.0.0", "ws": "~7.4.2" }, "devDependencies": { @@ -38,26 +42,27 @@ "eiows": "^3.3.0", "engine.io-client": "5.2.0", "engine.io-client-v3": "npm:engine.io-client@3.5.0", - "eslint": "^4.19.1", - "eslint-config-prettier": "^6.9.0", "expect.js": "^0.3.1", "mocha": "^4.0.1", "prettier": "^1.19.1", + "rimraf": "^3.0.2", "s": "0.1.1", - "superagent": "^3.8.1" + "superagent": "^3.8.1", + "typescript": "^4.4.3" }, "scripts": { - "lint": "eslint lib/ test/ *.js", - "test": "npm run lint && npm run format:check && mocha && EIO_CLIENT=3 mocha && EIO_WS_ENGINE=eiows mocha", - "format:check": "prettier --check 'lib/**/*.js' 'test/**/*.js'", - "format:fix": "prettier --write 'lib/**/*.js' 'test/**/*.js'" + "compile": "rimraf ./build && tsc", + "test": "npm run compile && npm run format:check && mocha --bail && EIO_CLIENT=3 mocha && EIO_WS_ENGINE=eiows mocha", + "format:check": "prettier --check 'lib/**/*.ts' 'test/**/*.js'", + "format:fix": "prettier --write 'lib/**/*.ts' 'test/**/*.js'", + "prepack": "npm run compile" }, "repository": { "type": "git", "url": "git@github.com:socketio/engine.io.git" }, "files": [ - "lib/" + "build/" ], "engines": { "node": ">=10.0.0" diff --git a/test/common.js b/test/common.js index 1e747e412..8cea5afc8 100644 --- a/test/common.js +++ b/test/common.js @@ -1,4 +1,4 @@ -const eio = require(".."); +const { listen } = require(".."); const eioc = process.env.EIO_CLIENT === "3" ? require("engine.io-client-v3") @@ -20,7 +20,7 @@ exports.listen = (opts, fn) => { opts.wsEngine = require(process.env.EIO_WS_ENGINE).Server; } - const e = eio.listen(0, opts, () => { + const e = listen(0, opts, () => { fn(e.httpServer.address().port); }); diff --git a/test/engine.io.js b/test/engine.io.js index 23f7034e6..5b76c9819 100644 --- a/test/engine.io.js +++ b/test/engine.io.js @@ -1,5 +1,5 @@ const net = require("net"); -const eio = require(".."); +const { Server, protocol, attach } = require(".."); const listen = require("./common").listen; const expect = require("expect.js"); const request = require("superagent"); @@ -11,7 +11,7 @@ const http = require("http"); describe("engine", () => { it("should expose protocol number", () => { - expect(eio.protocol).to.be.a("number"); + expect(protocol).to.be.a("number"); }); it("should be the same version as client", () => { @@ -21,13 +21,13 @@ describe("engine", () => { describe("engine()", () => { it("should create a Server when require called with no arguments", () => { - const engine = eio(); - expect(engine).to.be.an(eio.Server); + const engine = new Server(); + expect(engine).to.be.an(Server); expect(engine.ws).to.be.ok(); }); it("should pass options correctly to the Server", () => { - const engine = eio({ cors: true }); + const engine = new Server({ cors: true }); expect(engine.opts).to.have.property("cors", true); }); }); @@ -47,21 +47,21 @@ describe("engine", () => { describe("attach()", () => { it("should work from require()", () => { const server = http.createServer(); - const engine = eio(server); + const engine = new Server(server); - expect(engine).to.be.an(eio.Server); + expect(engine).to.be.an(Server); }); it("should return an engine.Server", () => { const server = http.createServer(); - const engine = eio.attach(server); + const engine = attach(server); - expect(engine).to.be.an(eio.Server); + expect(engine).to.be.an(Server); }); it("should attach engine to an http server", done => { const server = http.createServer(); - eio.attach(server); + attach(server); server.listen(() => { const uri = "http://localhost:%d/engine.io/default/".s( @@ -80,7 +80,7 @@ describe("engine", () => { it("should destroy upgrades not handled by engine", done => { const server = http.createServer(); - eio.attach(server, { destroyUpgradeTimeout: 50 }); + attach(server, { destroyUpgradeTimeout: 50 }); server.listen(() => { const client = net.createConnection(server.address().port); @@ -108,7 +108,7 @@ describe("engine", () => { it("should not destroy unhandled upgrades with destroyUpgrade:false", done => { const server = http.createServer(); - eio.attach(server, { destroyUpgrade: false, destroyUpgradeTimeout: 50 }); + attach(server, { destroyUpgrade: false, destroyUpgradeTimeout: 50 }); server.listen(() => { const client = net.createConnection(server.address().port); @@ -140,7 +140,7 @@ describe("engine", () => { it("should destroy unhandled upgrades with after a timeout", done => { const server = http.createServer(); - eio.attach(server, { destroyUpgradeTimeout: 200 }); + attach(server, { destroyUpgradeTimeout: 200 }); server.listen(() => { const client = net.createConnection(server.address().port); @@ -174,7 +174,7 @@ describe("engine", () => { it("should not destroy handled upgrades with after a timeout", done => { const server = http.createServer(); - eio.attach(server, { destroyUpgradeTimeout: 100 }); + attach(server, { destroyUpgradeTimeout: 100 }); // write to the socket to keep engine.io from closing it by writing before the timeout server.on("upgrade", (req, socket) => { @@ -226,7 +226,7 @@ describe("engine", () => { listeners++; }); - eio.attach(server); + attach(server); server.listen(() => { const port = server.address().port; diff --git a/test/server.js b/test/server.js index b8a60b55c..3b72c564b 100644 --- a/test/server.js +++ b/test/server.js @@ -6,7 +6,7 @@ const fs = require("fs"); const path = require("path"); const exec = require("child_process").exec; const zlib = require("zlib"); -const eio = require(".."); +const { Server, Socket, attach } = require(".."); const { eioc, listen, createPartialDone } = require("./common"); const expect = require("expect.js"); const request = require("superagent"); @@ -163,8 +163,8 @@ describe("server", () => { it("should send the io cookie", done => { listen({ cookie: true }, port => { request - .get("http://localhost:%d/engine.io/default/".s(port)) - .query({ transport: "polling", b64: 1 }) + .get("http://localhost:%d/engine.io/".s(port)) + .query({ transport: "polling", EIO: 4 }) .end((err, res) => { expect(err).to.be(null); // hack-obtain sid @@ -428,7 +428,7 @@ describe("server", () => { const engine = listen({ allowUpgrades: false }, port => { eioc("ws://localhost:%d".s(port)); engine.on("connection", socket => { - expect(socket).to.be.an(eio.Socket); + expect(socket).to.be.an(Socket); done(); }); }); @@ -606,7 +606,7 @@ describe("server", () => { // we can't send an invalid header through request.get // so add an invalid char here engine.prepare = function(req) { - eio.Server.prototype.prepare.call(engine, req); + Server.prototype.prepare.call(engine, req); req.headers.origin += "\n"; }; @@ -662,7 +662,7 @@ describe("server", () => { const partialDone = createPartialDone(done, 2); const httpServer = http.createServer(); - const engine = eio({ allowEIO3: false }); + const engine = new Server({ allowEIO3: false }); engine.attach(httpServer); httpServer.listen(() => { const port = httpServer.address().port; @@ -2061,7 +2061,7 @@ describe("server", () => { res.end("hello world\n"); }); - const engine = eio({ + const engine = new Server({ transports: ["polling"], allowUpgrades: false, allowEIO3: true @@ -2103,7 +2103,7 @@ describe("server", () => { res.end("hello world\n"); }); - const engine = eio({ + const engine = new Server({ transports: ["polling"], allowUpgrades: false, allowEIO3: true @@ -2147,7 +2147,7 @@ describe("server", () => { res.end("hello world\n"); }); - const engine = eio({ + const engine = new Server({ transports: ["websocket"], allowUpgrades: false, allowEIO3: true @@ -2190,7 +2190,7 @@ describe("server", () => { res.end("hello world\n"); }); - const engine = eio({ + const engine = new Server({ transports: ["polling"], allowUpgrades: false, allowEIO3: true @@ -2233,7 +2233,7 @@ describe("server", () => { res.end("hello world\n"); }); - const engine = eio({ + const engine = new Server({ transports: ["websocket"], allowUpgrades: false, allowEIO3: true @@ -2856,7 +2856,7 @@ describe("server", () => { }); // attach another engine to make sure it doesn't break upgrades - eio.attach(engine.httpServer, { path: "/foo" }); + attach(engine.httpServer, { path: "/foo" }); }); }); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..72ed6e2d5 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "outDir": "build/", + "target": "es2018", // Node.js 10 (https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping) + "module": "commonjs", + "declaration": true + }, + "include": [ + "./lib/**/*" + ] +}