import http from 'http' import { Server, ServerOptions } from 'socket.io' import { createDebug } from '@feathersjs/commons' import { Application, RealTimeConnection } from '@feathersjs/feathers' import { socket } from '@feathersjs/transport-commons' import { disconnect, params, authentication, FeathersSocket } from './middleware' const debug = createDebug('@feathersjs/socketio') declare module '@feathersjs/feathers/lib/declarations' { // eslint-disable-next-line @typescript-eslint/no-unused-vars interface Application { io: any listen(options: any): Promise } } function configureSocketio(callback?: (io: Server) => void): (app: Application) => void function configureSocketio( options: number | Partial, callback?: (io: Server) => void ): (app: Application) => void function configureSocketio( port: number, options?: Partial, callback?: (io: Server) => void ): (app: Application) => void function configureSocketio(port?: any, options?: any, config?: any) { if (typeof port !== 'number') { config = options options = port port = null } if (typeof options !== 'object') { config = options options = {} } return (app: Application) => { // Function that gets the connection const getParams = (socket: FeathersSocket) => socket.feathers // A mapping from connection to socket instance const socketMap = new WeakMap() // Promise that resolves with the Socket.io `io` instance // when `setup` has been called (with a server) const done = new Promise((resolve) => { const { listen, setup } = app as any Object.assign(app, { async listen(this: any, ...args: any[]) { if (typeof listen === 'function') { // If `listen` already exists // usually the case when the app has been expressified return listen.call(this, ...args) } const server = http.createServer() await this.setup(server) return server.listen(...args) }, async setup(this: any, server: http.Server, ...rest: any[]) { if (!this.io) { const io = (this.io = new Server(port || server, options)) io.use(disconnect(app, getParams, socketMap)) io.use(params(app, socketMap)) io.use(authentication(app, getParams)) // In Feathers it is easy to hit the standard Node warning limit // of event listeners (e.g. by registering 10 services). // So we set it to a higher number. 64 should be enough for everyone. io.sockets.setMaxListeners(64) } if (typeof config === 'function') { debug('Calling SocketIO configuration function') config.call(this, this.io) } resolve(this.io) return setup.call(this, server, ...rest) } }) }) app.configure( socket({ done, socketMap, getParams, emit: 'emit' }) ) } } export = configureSocketio