UNPKG

moleculer-io

Version:

An API GateWay service for Moleculer using Socket.IO

172 lines (162 loc) 5.56 kB
declare module "moleculer-io" { import { DefaultEventsMap, EventsMap } from "socket.io/dist/typed-events"; import { Client } from "socket.io/dist/client"; import { Server, ServerOptions, Socket } from "socket.io"; import { Context, ServiceSchema, CallingOptions, ServiceMethods, ServiceSettingSchema, Service } from "moleculer"; import { ApiSettingsSchema } from "moleculer-web"; import * as http from "http"; import { SocketOptions } from "socket.io-client"; class ClientMoleculerIO< ClientUser, ListenEvents extends EventsMap, EmitEvents extends EventsMap, ServerSideEvents extends EventsMap > extends Client<ListenEvents, EmitEvents, ServerSideEvents> { user?: ClientUser; } export class SocketMoleculerIO< ClientUser = unknown, ServiceSettings = ServiceSettingSchema, ListenEvents extends EventsMap = DefaultEventsMap, EmitEvents extends EventsMap = ListenEvents, ServerSideEvents extends EventsMap = DefaultEventsMap > extends Socket<ListenEvents, EmitEvents, ServerSideEvents> { readonly $service: Service<ServiceSettings>; readonly client: ClientMoleculerIO<ClientUser, ListenEvents, EmitEvents, ServerSideEvents>; } interface NamespaceEvent { /** * The `event` has a `mappingPolicy` property to handle events without aliases. * - all - enable to handle all actions with or without aliases (default) * - restrict - enable to handle only the actions with aliases * @see https://moleculer.services/docs/0.14/moleculer-web.html#Mapping-policy * @default: "all" */ mappingPolicy: "all" | "restrict"; /** * You can use alias names instead of action names. * @example { * add: "math.add" * } * socket.emit("call", "add", {a: 1, b: 2}); */ aliases: Record<string, string>; whitelist: string[]; callOptions: Partial<CallingOptions>; /** * The event handler has before & after call hooks. You can use it to set ctx.meta, access socket object or modify the response data * @see https://github.com/moleculerjs/moleculer-io#handler-hooks */ onBeforeCall<P = any>( ctx: Context<Record<string, any>, Record<any, any>>, socket: SocketMoleculerIO, action: string, params: P, callOptions: CallingOptions ): Promise<void>; /** * The event handler has before & after call hooks. You can use it to set ctx.meta, access socket object or modify the response data * @see https://github.com/moleculerjs/moleculer-io#handler-hooks */ onAfterCall<ORIGINAL_RES = any, MODIFIED_RES = any>( ctx: Context<Record<string, any>>, socket: SocketMoleculerIO, res: ORIGINAL_RES ): Promise<void | MODIFIED_RES>; } type NamespaceMiddlewareFunction = Parameters<Server["use"]>[0]; type SocketMiddlewareFunction = Parameters<Socket["use"]>[0]; /** * Custom event's handler as a function.<br> * Last params will be `response function` if client called `socket.emit('event', ..., aFunction(...){...})`.<br> * * @example { * events: { * // callback (if exists) only accept 2 params: first is error, last is data * example(arg1: string, arg2: number, response: (...data: any[]) => void) { * response(arg1, arg2) * }, * exp2(arg1: string, arg2: number, callback: (err?: Error, ...data: any[]) => void) { * callback(null, arg1, arg2) * }, * }, * } * @see https://socket.io/docs/v4/server-api/#socketoneventname-callback */ type EventCustomFunction<T = unknown> = ( this: SocketMoleculerIO, ...args: T[] ) => void | Promise<void>; interface IONamespace { authorization?: boolean; middlewares?: NamespaceMiddlewareFunction[]; packetMiddlewares?: SocketMiddlewareFunction[]; events: { call: Partial<NamespaceEvent> | EventCustomFunction; [k: string]: Partial<NamespaceEvent> | EventCustomFunction; }; } export interface IOSetting { options?: Partial<ServerOptions>; namespaces: { [k: string]: IONamespace; }; } type InitSocketIOFunction = (srv: http.Server, opts: SocketOptions) => void; type SocketAuthorizeFunction = <USER = unknown>( socket: Socket, handlerItem: IONamespace ) => Promise<USER | void>; type SocketGetMetaFunction = < META = { user: any; $rooms: string[]; } >( socket: SocketMoleculerIO ) => Promise<META>; type SocketSaveMetaFunction = ( socket: SocketMoleculerIO, ctx: Context<any, any> ) => Promise<void>; type SocketSaveUserFunction = (socket: Socket, user: any) => Promise<void>; type SocketOnErrorFunction = ( err: Error, respond: (error: Error | null, ...data: any[]) => void ) => void; type SocketJoinRoomsFunction = (socket: SocketMoleculerIO, rooms: string | string[]) => void; type SocketLeaveRoomFunction = (socket: SocketMoleculerIO, room: string) => void; interface IOMethods extends ServiceMethods { initSocketIO: InitSocketIOFunction; socketAuthorize: SocketAuthorizeFunction; socketGetMeta: SocketGetMetaFunction; /** * by default, will call socketSaveUser(socket, ctx.meta.user) */ socketSaveMeta: SocketSaveMetaFunction; /** * by default, will set user to socket.client.user */ socketSaveUser: SocketSaveUserFunction; socketOnError: SocketOnErrorFunction; socketJoinRooms: SocketJoinRoomsFunction; socketLeaveRoom: SocketLeaveRoomFunction; } export interface IOServiceSchema extends ServiceSchema< ApiSettingsSchema & { io?: IOSetting; } > { methods: Partial<IOMethods> & ThisType<IOServiceSchema>; } const SocketIOMixin: Partial<IOServiceSchema>; export default SocketIOMixin; }