UNPKG

3.21 kBJavaScriptView Raw
1'use strict'
2
3const ExecInfo = require('./ExecInfo')
4const Promise = require('bluebird')
5const _ = require('lodash')
6const { execHook, logError, possiblyCallback, resultsTransform } =
7 require('./utils')
8
9// Implements command functions binding and wrapping.
10class CommandBinder {
11
12 constructor (server, transport, userName) {
13 this.server = server
14 this.transport = transport
15 this.userName = userName
16 }
17
18 commandWatcher (id, name) {
19 this.server.runningCommands++
20 return Promise.resolve().disposer(() => {
21 this.server.runningCommands--
22 if (this.transport.closed && this.server.runningCommands <= 0) {
23 this.server.emit('commandsFinished')
24 }
25 })
26 }
27
28 makeCommand (name, fn) {
29 let { validator } = this.server
30 let beforeHook = this.server.hooks[`${name}Before`]
31 let afterHook = this.server.hooks[`${name}After`]
32 return (args, info) => {
33 let execInfo = new ExecInfo()
34 _.assign(execInfo, { server: this.server, userName: this.userName })
35 _.assign(execInfo, info)
36 _.assign(execInfo, validator.splitArguments(name, args))
37 return Promise.using(
38 this.commandWatcher(info.id, name),
39 () => validator.checkArguments(name, ...execInfo.args)
40 .then(() => {
41 if (beforeHook && !execInfo.bypassHooks) {
42 return execHook(beforeHook, execInfo)
43 } else {
44 return Promise.resolve()
45 } })
46 .then(results => {
47 if (results && results.length) { return results }
48 return fn(...execInfo.args, execInfo)
49 .then(result => { execInfo.results = [result] },
50 error => { execInfo.error = error })
51 .then(() => {
52 if (afterHook && !execInfo.bypassHooks) {
53 return execHook(afterHook, execInfo)
54 } else {
55 return Promise.resolve()
56 } })
57 .then(results => {
58 if (results && results.length) {
59 return results
60 } else if (execInfo.error) {
61 return Promise.reject(execInfo.error)
62 } else {
63 return execInfo.results
64 }
65 })
66 }))
67 .catch(error => logError(error))
68 }
69 }
70
71 bindDisconnect (id, fn) {
72 let server = this.server
73 let hook = this.server.hooks.onDisconnect
74 this.transport.bindHandler(id, 'disconnect', () => {
75 return Promise.using(
76 this.commandWatcher(id, 'disconnect'),
77 () => fn(id)
78 .catch(error => logError(error))
79 .catchReturn()
80 .then(() => execHook(hook, server, id))
81 .catch(error => logError(error))
82 .catchReturn())
83 })
84 }
85
86 bindCommand (id, name, fn) {
87 let cmd = this.makeCommand(name, fn)
88 let useErrorObjects = this.server.useRawErrorObjects
89 let info = {id}
90 return this.transport.bindHandler(id, name, function () {
91 let [args, cb] = possiblyCallback(arguments)
92 let ack = resultsTransform(useErrorObjects, cb)
93 return cmd(args, info).asCallback(ack, { spread: true })
94 })
95 }
96
97}
98
99module.exports = CommandBinder