/// import { EventEmitter } from "events"; import * as http from "http"; import { ParsedUrlQuery } from "querystring"; import { Stream } from "stream"; export = Primus; // https://github.com/primus/emits // This can't be typed correctly // - https://github.com/microsoft/TypeScript/issues/1360 // - https://stackoverflow.com/questions/22043041/typescript-rest-parameter-in-the-middle-of-arguments-list declare namespace emits { interface done { (err: Error | null | undefined, arg: any): void; } interface parser { (done: done, ...args: any[]): void; } interface fn { (...args: any[]): boolean; } interface emits { (event: string, parser: parser): fn; (event: string, arg1: any, parser: parser): fn; (event: string, ...args: any[]): fn; } } interface PrimusPacket { data: unknown; } interface Parser { encoder: (data: any, fn: (error: Error, response: any) => void) => void; decoder: (data: any, fn: (error: Error, response: any) => void) => void; } type AuthorizationHandler = ( req: http.IncomingMessage, done: ( err?: string | Error | { statusCode?: number | undefined; authenticate?: string | undefined; message?: string | undefined; }, ) => void, ) => void; type Middleware = (req: http.IncomingMessage, res: http.ServerResponse) => void; declare class Primus extends EventEmitter { on(event: "plugin" | "plugout", cb: (name: string, energon: unknown) => void): this; on(event: "connection" | "disconnection", cb: (spark: Primus.Spark) => void): this; constructor(server: http.Server, options?: PrimusOptions); authorize(fn: AuthorizationHandler): this; forEach(cb: (spark: Primus.Spark) => boolean): this; forEach( cb: (spark: Primus.Spark, next: (err: Error | null, forward: boolean) => void) => void, done: (err: Error | null) => void, ): this; connections: { [id: string]: Primus.Spark }; connected: number; write(data: any): void; transform(type: "incoming" | "outgoing", fn: (packet: PrimusPacket) => void): this; // This is marked as private in the source code, but documented in the readme spark(id: string): Primus.Spark; library(): string; // This has a lot of variations and can be improved plugin(): { [name: string]: unknown }; plugin(name?: string): unknown; plugin(energon: { name: string }): this; plugin(name: string, energon: string | { name: string }): this; plugout(name: string): this; use(fn: () => Middleware | Middleware, options?: object, level?: number): this; use(name: string, fn: () => Middleware | Middleware, options?: object, level?: number): this; remove(name: string): this; enable(name: string): this; disable(name: string): this; destroy(options: { close?: boolean | undefined; reconnect: boolean; timeout: number }, fn: () => void): this; end(data?: any, options?: { reconnect?: boolean | undefined }): void; reserved(name: string): boolean; emits: emits.emits; Socket: typeof Primus.Socket; } interface PrimusOptions { authorization?: AuthorizationHandler | undefined; pathname?: string | undefined; parser?: string | Parser | undefined; transformer?: "websockets" | "engine.io" | "browserchannel" | "sockjs" | "faye" | "uws" | undefined; plugin?: string | object | undefined; pingInterval?: number | undefined; global?: string | undefined; compression?: boolean | undefined; maxLength?: number | undefined; transport?: object | undefined; idGenerator?(): string; // Cors origins?: string | undefined; methods?: string | undefined; credentials?: boolean | undefined; maxAge?: string | undefined; headers?: boolean | undefined; exposed?: boolean | undefined; } declare namespace Primus { function createSocket(options?: SocketOptions): typeof Socket; function createServer(options?: PrimusOptions): Primus; function createServer(fn: (spark: Spark) => void, options?: PrimusOptions): Primus; interface Spark extends Stream { headers: http.IncomingHttpHeaders; address: { ip: string; secure: boolean; port: number; }; query: ParsedUrlQuery; socket: unknown; id: string; request: http.IncomingMessage; write(data: any): void; end(data?: any, options?: { reconnect?: boolean | undefined }): void; emits: emits.emits; on(event: "data", handler: (message: any) => void): this; on(event: "end", handler: () => void): this; } interface ReconnectOpts { max?: number | undefined; min?: number | undefined; retries?: number | null | undefined; "reconnect timeout"?: number | undefined; factor?: number | undefined; } interface ReconnectEventOpts extends Required { start: number; duration: number; attempt: number; backoff: boolean; scheduled: number; } interface SocketOptions { // https://github.com/unshiftio/recovery reconnect?: { max?: number | undefined; min?: number | undefined; retries?: number | undefined; "reconnect timeout"?: number | undefined; factor?: number | undefined; } | undefined; timeout?: number | undefined; pingTimeout?: number | undefined; strategy?: string | Array<"disconnect" | "online" | "timeout"> | undefined; manual?: boolean | undefined; websockets?: boolean | undefined; network?: boolean | undefined; transport?: object | undefined; queueSize?: number | undefined; // https://www.npmjs.com/package/primus#connecting-from-the-server transformer?: PrimusOptions["transformer"] | undefined; parser?: PrimusOptions["parser"] | undefined; plugin?: PrimusOptions["plugin"] | undefined; } class Socket extends Stream { constructor(options?: SocketOptions); constructor(url?: string, options?: SocketOptions); write(data: any): this; end(data?: any): this; destroy(): void; emits: emits.emits; id(fn: (id: string) => void): this; on(event: "open" | "end", handler: () => void): this; on( event: "reconnect" | "reconnect scheduled" | "reconnected", handler: (opts: ReconnectEventOpts) => void, ): this; on( event: "reconnect timeout" | "reconnect failed", handler: (err: Error, opts: ReconnectEventOpts) => void, ): this; on(event: "data", handler: (message: any) => void): this; on(event: "error", handler: (err: Error) => void): this; open(): this; } }