UNPKG

@feathersjs/transport-commons

Version:

Shared functionality for websocket providers

99 lines 4.63 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.paramsPositions = exports.DEFAULT_PARAMS_POSITION = void 0; exports.normalizeError = normalizeError; exports.getDispatcher = getDispatcher; exports.runMethod = runMethod; const feathers_1 = require("@feathersjs/feathers"); const errors_1 = require("@feathersjs/errors"); const commons_1 = require("@feathersjs/commons"); const isEqual_1 = __importDefault(require("lodash/isEqual")); const debug = (0, commons_1.createDebug)('@feathersjs/transport-commons'); exports.DEFAULT_PARAMS_POSITION = 1; exports.paramsPositions = { find: 0, update: 2, patch: 2 }; function normalizeError(e) { const hasToJSON = typeof e.toJSON === 'function'; const result = hasToJSON ? e.toJSON() : {}; if (!hasToJSON) { Object.getOwnPropertyNames(e).forEach((key) => { result[key] = e[key]; }); } if (process.env.NODE_ENV === 'production') { delete result.stack; } delete result.hook; return result; } function getDispatcher(emit, socketMap, socketKey) { return function (event, channel, context, data) { debug(`Dispatching '${event}' to ${channel.length} connections`); channel.connections.forEach((connection) => { // The reference between connection and socket is set in `app.setup` const socket = socketKey ? connection[socketKey] : socketMap.get(connection); if (socket) { const eventName = `${context.path || ''} ${event}`.trim(); let result = channel.dataFor(connection) || context.dispatch || context.result; // If we are getting events from an array but try to dispatch individual data // try to get the individual item to dispatch from the correct index. if (!Array.isArray(data) && Array.isArray(context.result) && Array.isArray(result)) { result = result.find((resultData) => (0, isEqual_1.default)(resultData, data)); } debug(`Dispatching '${eventName}' to Socket ${socket.id} with`, result); socket[emit](eventName, result); } }); }; } async function runMethod(app, connection, _path, _method, args) { const path = typeof _path === 'string' ? _path : null; const method = typeof _method === 'string' ? _method : null; const trace = `method '${method}' on service '${path}'`; const methodArgs = args.slice(0); const callback = // eslint-disable-next-line @typescript-eslint/no-empty-function typeof methodArgs[methodArgs.length - 1] === 'function' ? methodArgs.pop() : function () { }; debug(`Running ${trace}`, connection, args); const handleError = (error) => { debug(`Error in ${trace}`, error); callback(normalizeError(error)); }; try { const lookup = app.lookup(path); // No valid service was found throw a NotFound error if (lookup === null) { throw new errors_1.NotFound(path === null ? `Invalid service path` : `Service '${path}' not found`); } const { service, params: route = {} } = lookup; const { methods } = (0, feathers_1.getServiceOptions)(service); // Only service methods are allowed if (!methods.includes(method)) { throw new errors_1.MethodNotAllowed(`Method '${method}' not allowed on service '${path}'`); } const position = exports.paramsPositions[method] !== undefined ? exports.paramsPositions[method] : exports.DEFAULT_PARAMS_POSITION; const query = Object.assign({}, methodArgs[position]); // `params` have to be re-mapped to the query and added with the route const params = Object.assign({ query, route, connection }, connection); // `params` is always the last parameter. Error if we got more arguments. if (methodArgs.length > position + 1) { throw new errors_1.BadRequest(`Too many arguments for '${method}' method`); } methodArgs[position] = params; const ctx = (0, feathers_1.createContext)(service, method); const returnedCtx = await service[method](...methodArgs, ctx); const result = returnedCtx.dispatch || returnedCtx.result; debug(`Returned successfully ${trace}`, result); callback(null, result); } catch (error) { handleError(error); } } //# sourceMappingURL=utils.js.map