chat-platform 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/helpers/lcd.js ADDED
@@ -0,0 +1,120 @@
1
+ var clc = require('cli-color');
2
+ var _ = require('underscore');
3
+ var prettyjson = require('prettyjson');
4
+ var moment = require('moment');
5
+
6
+ var warn = clc.yellow;
7
+ var grey = clc.blackBright;
8
+ var green = clc.greenBright;
9
+ var white = clc.white;
10
+ var orange = clc.xterm(214);
11
+ var whiteBright = clc.whiteBright;
12
+ var red = clc.red;
13
+
14
+ var LCD = {
15
+
16
+ warn: warn,
17
+ error: orange,
18
+ grey: grey,
19
+ green: green,
20
+ white: white,
21
+ orange: orange,
22
+ red: red,
23
+
24
+ dump: function(e, title) {
25
+ this.title(!_.isEmpty(title) ? title : 'Error');
26
+ if (e instanceof Error) {
27
+ Error.captureStackTrace(e);
28
+ var lines = e.stack.split('\n');
29
+ lines.shift();
30
+ lines.shift();
31
+ // is there a better way to get this?
32
+ var reference = e.toString().replace(e.message, '').replace(': ', '');
33
+ // eslint-disable-next-line no-console
34
+ console.log(whiteBright(reference) + ': ' + red(e.message));
35
+ // eslint-disable-next-line no-console
36
+ console.log(this.grey(lines.join('\n')));
37
+ } else {
38
+ // eslint-disable-next-line no-console
39
+ console.log(e);
40
+ }
41
+ // eslint-disable-next-line no-console
42
+ console.log('');
43
+ },
44
+
45
+ beautify: function(payload) {
46
+ if (payload == null) {
47
+ return payload;
48
+ }
49
+ payload = _.clone(payload);
50
+ _(payload).each(function(value, key) {
51
+ if (value instanceof Buffer) {
52
+ payload[key] = '<Buffer>';
53
+ } else if (value instanceof moment) {
54
+ payload[key] = value.toString();
55
+ }
56
+ });
57
+ return payload;
58
+ },
59
+
60
+ title: function(title) {
61
+ title = ' ' + title + ' ';
62
+ var padding = Math.floor((80 - title.length)/2);
63
+ _.times(padding, function() {
64
+ title = '-' + title;
65
+ });
66
+ while (title.length < 80) {
67
+ title += '-';
68
+ }
69
+ // eslint-disable-next-line no-console
70
+ console.log(grey(title));
71
+ },
72
+
73
+ node: function(obj, options) {
74
+
75
+ options = _.extend({
76
+ nodeId: null,
77
+ title: null,
78
+ color: function(value) {
79
+ return value;
80
+ }
81
+ }, options);
82
+
83
+ // eslint-disable-next-line no-console
84
+ console.log('');
85
+
86
+ var title = '';
87
+ if (!_.isEmpty(options.title)) {
88
+ title += options.title;
89
+ }
90
+ if (options.node != null) {
91
+ title += ' (id:' + options.node.id + ')';
92
+ }
93
+
94
+ if (!_.isEmpty(title)) {
95
+ title = ' ' + title + ' ';
96
+ var padding = Math.floor((80 - title.length)/2);
97
+ _.times(padding, function() {
98
+ title = '-' + title;
99
+ });
100
+ while (title.length < 80) {
101
+ title += '-';
102
+ }
103
+ // eslint-disable-next-line no-console
104
+ console.log(grey(title));
105
+ }
106
+
107
+ if (_.isString(obj)) {
108
+ // eslint-disable-next-line no-console
109
+ console.log(options.color(obj));
110
+ } else {
111
+ // eslint-disable-next-line no-console
112
+ console.log(prettyjson.render(LCD.beautify(obj)));
113
+ }
114
+ // eslint-disable-next-line no-console
115
+ console.log('');
116
+ }
117
+
118
+ };
119
+
120
+ module.exports = LCD;
@@ -0,0 +1,41 @@
1
+ var _ = require('underscore');
2
+
3
+ var FileQueue = function() {
4
+ var tasks = [];
5
+ function removeTask(promise) {
6
+ tasks = _(tasks).reject(function(task) {
7
+ return task === promise;
8
+ });
9
+ }
10
+
11
+ return {
12
+
13
+ count: function() {
14
+ return tasks.length;
15
+ },
16
+
17
+ add: function(task) {
18
+ var current = null;
19
+ if (tasks.length === 0) {
20
+ // if it's just one task then launch it
21
+ current = new Promise(task);
22
+ } else {
23
+ // only chain when all the current promises are fulfilled, it's ok since tasks is immutable
24
+ // even if some other task is chained after this
25
+ current = Promise.all(tasks)
26
+ .then(function() {
27
+ return new Promise(task);
28
+ });
29
+ }
30
+ // create new task list with the new one, it's important to create a new instance
31
+ tasks = tasks.concat(current);
32
+ // return the promise, when is done remove from the current task
33
+ return current
34
+ .then(function() {
35
+ removeTask(current);
36
+ });
37
+ }
38
+ };
39
+ };
40
+
41
+ module.exports = FileQueue;
@@ -0,0 +1,25 @@
1
+ const _ = require('underscore');
2
+
3
+ module.exports = {
4
+
5
+ /**
6
+ * @method when
7
+ * If an object is thenable, then return the object itself, otherwise wrap it into a promise
8
+ * @param param {any}
9
+ * @deferred
10
+ */
11
+ when(param) {
12
+ if (param != null && _.isFunction(param.then)) {
13
+ return param;
14
+ // eslint-disable-next-line no-undefined
15
+ } else if (param !== undefined) {
16
+ return new Promise(function(resolve) {
17
+ resolve(param);
18
+ });
19
+ }
20
+ return new Promise(function(resolve, reject) {
21
+ reject();
22
+ });
23
+ }
24
+
25
+ };
package/index.js ADDED
@@ -0,0 +1,6 @@
1
+ const ChatExpress = require('./chat-platform');
2
+ const ContextProviders = require('./chat-context-factory');
3
+ const ChatLog = require('./chat-log');
4
+ const UniversalPlatform = require('./universal');
5
+
6
+ module.exports = { ChatExpress, ContextProviders, ChatLog, UniversalPlatform };
package/jest.config.js ADDED
@@ -0,0 +1,5 @@
1
+ // jest.config.js
2
+ module.exports = {
3
+ verbose: true,
4
+ testURL: 'http://localhost'
5
+ };
package/lib/lcd.js ADDED
@@ -0,0 +1,151 @@
1
+ var clc = require('cli-color');
2
+ var _ = require('underscore');
3
+ var prettyjson = require('prettyjson');
4
+ var moment = require('moment');
5
+
6
+ var warn = clc.yellow;
7
+ var grey = clc.blackBright;
8
+ var green = clc.greenBright;
9
+ var white = clc.white;
10
+ var orange = clc.xterm(214);
11
+ var whiteBright = clc.whiteBright;
12
+ var red = clc.red;
13
+
14
+ var LCD = {
15
+
16
+ warn: warn,
17
+ error: orange,
18
+ grey: grey,
19
+ green: green,
20
+ white: white,
21
+ orange: orange,
22
+ red: red,
23
+
24
+ timestamp() {
25
+ return LCD.white(moment().format('DD MMM HH:mm:ss') + ' - [info] ');
26
+ },
27
+
28
+ dump: function(e, title) {
29
+ this.title(!_.isEmpty(title) ? title : 'Error');
30
+ if (e instanceof Error) {
31
+ Error.captureStackTrace(e);
32
+ var lines = e.stack.split('\n');
33
+ lines.shift();
34
+ lines.shift();
35
+ // is there a better way to get this?
36
+ var reference = e.toString().replace(e.message, '').replace(': ', '');
37
+ // eslint-disable-next-line no-console
38
+ console.log(whiteBright(reference) + ': ' + red(e.message));
39
+ // eslint-disable-next-line no-console
40
+ console.log(this.grey(lines.join('\n')));
41
+ } else if (_.isArray(e)) {
42
+ // eslint-disable-next-line no-console
43
+ console.log(prettyjson.render(LCD.beautify(e)));
44
+ } else {
45
+ // eslint-disable-next-line no-console
46
+ console.log(e);
47
+ }
48
+ // eslint-disable-next-line no-console
49
+ console.log('');
50
+ },
51
+
52
+ beautify: function(payload) {
53
+ if (payload == null) {
54
+ return payload;
55
+ }
56
+ payload = _.clone(payload);
57
+ _(payload).each(function(value, key) {
58
+ if (value instanceof Buffer) {
59
+ payload[key] = '<Buffer>';
60
+ } else if (value instanceof moment) {
61
+ payload[key] = value.toString();
62
+ }
63
+ });
64
+ return payload;
65
+ },
66
+
67
+ title: function(title) {
68
+ title = ' ' + title + ' ';
69
+ var padding = Math.floor((80 - title.length)/2);
70
+ _.times(padding, function() {
71
+ title = '-' + title;
72
+ });
73
+ while (title.length < 80) {
74
+ title += '-';
75
+ }
76
+ // eslint-disable-next-line no-console
77
+ console.log(grey(title));
78
+ },
79
+
80
+ prettify: function(obj, { indent = 0 } = {}) {
81
+ let rendered = prettyjson.render(LCD.beautify(obj));
82
+ if (_.isNumber(indent) && indent != 0) {
83
+ rendered = ' ' + rendered.replace(/[\n]/g, "\n ");
84
+ }
85
+ return rendered;
86
+ },
87
+
88
+ node: function(obj, options) {
89
+
90
+ options = _.extend({
91
+ nodeId: null,
92
+ title: null,
93
+ color: function(value) {
94
+ return value;
95
+ }
96
+ }, options);
97
+
98
+ // eslint-disable-next-line no-console
99
+ console.log('');
100
+
101
+ var title = '';
102
+ if (!_.isEmpty(options.title)) {
103
+ title += options.title;
104
+ }
105
+ if (options.node != null) {
106
+ title += ' (id:' + options.node.id + ')';
107
+ }
108
+
109
+ if (!_.isEmpty(title)) {
110
+ title = ' ' + title + ' ';
111
+ var padding = Math.floor((80 - title.length)/2);
112
+ _.times(padding, function() {
113
+ title = '-' + title;
114
+ });
115
+ while (title.length < 80) {
116
+ title += '-';
117
+ }
118
+ // eslint-disable-next-line no-console
119
+ console.log(grey(title));
120
+ }
121
+
122
+ if (_.isString(obj)) {
123
+ // eslint-disable-next-line no-console
124
+ console.log(options.color(obj));
125
+ } else {
126
+ // eslint-disable-next-line no-console
127
+ console.log(prettyjson.render(LCD.beautify(obj)));
128
+ }
129
+ // eslint-disable-next-line no-console
130
+ console.log('');
131
+ },
132
+
133
+ graphQLError: (error, node) => {
134
+ if (error != null && error.networkError != null && error.networkError.result != null && error.networkError.result.errors != null) {
135
+ let errors = error.networkError.result.errors.map(error => {
136
+ let errorMsg = error.message;
137
+ if (error.locations != null) {
138
+ errorMsg += ` (line: ${error.locations[0].line})`;
139
+ }
140
+ return errorMsg;
141
+ });
142
+ LCD.dump(errors, `GraphQL Error (id: ${node.id}${!_.isEmpty(node.name) ? ', name: ' + node.name : ''})`);
143
+ } else {
144
+ LCD.dump('Unknown GraphQL error', `GraphQL Error (id: ${node.id}${!_.isEmpty(node.name) ? ', name: ' + node.name : ''})`);
145
+ console.log(error);
146
+ }
147
+ }
148
+
149
+ };
150
+
151
+ module.exports = LCD;
@@ -0,0 +1,212 @@
1
+ /* eslint-disable */
2
+ var _ = require('underscore');
3
+ var ChatContextFactory = require('../chat-context-factory')({});
4
+ var ChatContextProvider = ChatContextFactory.getProvider('memory', {});
5
+
6
+ module.exports = function() {
7
+
8
+ var _cbInput = null;
9
+ var _type = null;
10
+ var _factory = null;
11
+ var _node = null;
12
+ var _config = null;
13
+ var _message = null;
14
+ var _flow = {};
15
+ var _global = {};
16
+ var _chatContext = null;
17
+ var _nodecontext = {};
18
+ var _error = null;
19
+ var _nodes = {};
20
+
21
+ var RED = {
22
+
23
+ global: {
24
+ get: function(key) {
25
+ return _global[key];
26
+ },
27
+ set: function(key, value) {
28
+ _global[key] = value;
29
+ return this;
30
+ }
31
+ },
32
+
33
+ util: {
34
+ cloneMessage: function(msg) {
35
+ return msg
36
+ }
37
+ },
38
+
39
+ environment: {
40
+ chat: function(chatId, obj) {
41
+ _(obj).map(function(value, key) {
42
+ _chatContext.set(key, value);
43
+ });
44
+ }
45
+ },
46
+
47
+ createMessage: function(payload, transport, global) {
48
+ var chatId = 42;
49
+ // create a chat context if doesn't exists
50
+
51
+ var msg = {
52
+ originalMessage: {
53
+ chatId: chatId,
54
+ transport: transport != null ? transport : 'telegram',
55
+ chat: {
56
+ id: chatId
57
+ },
58
+ message_id: 72
59
+ },
60
+ chat: function() {
61
+ return ChatContextProvider.getOrCreate(chatId);
62
+ },
63
+ payload: payload != null ? payload : 'I am the original message'
64
+ };
65
+ _global = _.extend({}, global);
66
+ //_chatContext = ChatContext(chatId);
67
+ //_chatContext.clear();
68
+ msg.chat().clear();
69
+ // store it
70
+ //ChatContextStore.set(chatId, _chatContext);
71
+ if (payload != null) {
72
+ msg.payload = payload;
73
+ }
74
+ return msg;
75
+ },
76
+
77
+ events: {
78
+ on: function() {
79
+ // do nothing
80
+ }
81
+ },
82
+
83
+ node: {
84
+ config: function(config) {
85
+ _config = config;
86
+ },
87
+ clear: function() {
88
+ _nodecontext = {};
89
+ },
90
+ message: function(idx) {
91
+ if (_.isArray(_message)) {
92
+ return idx != null ? _message[idx] : _message[0];
93
+ } else {
94
+ return _message;
95
+ }
96
+ },
97
+ error: function() {
98
+ return _error;
99
+ },
100
+ get: function(idx) {
101
+ return idx != null ? _node[idx] : _node;
102
+ },
103
+ context: function() {
104
+ return _node.context();
105
+ }
106
+ },
107
+
108
+ nodes: {
109
+ registerType: function(type, factory) {
110
+ _type = type;
111
+ _factory = factory;
112
+ factory(_config);
113
+ },
114
+
115
+ getNode: function(nodeId) {
116
+ return _nodes[nodeId];
117
+ },
118
+
119
+ setNode: function(nodeId, node) {
120
+ _nodes[nodeId] = node;
121
+ },
122
+
123
+ /**
124
+ * @method createNode
125
+ * Mock createdNode called when initializing a custom node
126
+ */
127
+ createNode: function(node, config) {
128
+
129
+ node.on = function(eventName, cb) {
130
+ if (eventName === 'input') {
131
+ _cbInput = cb;
132
+ }
133
+ };
134
+ node.emit = function(eventName, msg) {
135
+ if (eventName === 'input') {
136
+ _message = null;
137
+ _cbInput(msg);
138
+ }
139
+ };
140
+ node.await = function() {
141
+ var retries = 0;
142
+ var intervalId = null;
143
+ return new Promise(function(resolve, reject) {
144
+ intervalId = setInterval(function() {
145
+ if (_message !== null) {
146
+ clearInterval(intervalId);
147
+ resolve();
148
+ } else if (_error != null) {
149
+ clearInterval(intervalId);
150
+ reject(_error);
151
+ } else if (retries > 20) {
152
+ clearInterval(intervalId);
153
+ reject();
154
+ } else {
155
+ retries++;
156
+ }
157
+ }, 30);
158
+ });
159
+ };
160
+ node.send = function(msg) {
161
+ _message = msg;
162
+ };
163
+ node.error = function(msg) {
164
+ _error = msg;
165
+ };
166
+ node.context = function() {
167
+ return {
168
+ flow: {
169
+ get: function(key) {
170
+ return _flow[key];
171
+ },
172
+ set: function(key, value) {
173
+ _flow[key] = value;
174
+ return this;
175
+ }
176
+ },
177
+ global: _.extend({}, _global, {
178
+ get: function(key) {
179
+ return _global[key];
180
+ },
181
+ set: function(key, value) {
182
+ _global[key] = value;
183
+ return this;
184
+ }
185
+ }),
186
+ chat: {
187
+ get: function(key) {
188
+ return _chatContext.get(key);
189
+ },
190
+ set: function(key, value) {
191
+ _chatContext.set(key, value);
192
+ }
193
+ },
194
+ get: function(key) {
195
+ return _nodecontext[key];
196
+ },
197
+ set: function(key, value) {
198
+ _nodecontext[key] = value;
199
+ return this;
200
+ }
201
+ };
202
+ };
203
+ node.wires = [{}, null];
204
+ _node = node;
205
+ }
206
+ }
207
+
208
+ };
209
+
210
+ return RED;
211
+ };
212
+ /* eslint-enable */
package/lib/utils.js ADDED
@@ -0,0 +1,29 @@
1
+ const _ = require('underscore');
2
+
3
+ module.exports = {
4
+
5
+ isEmpty(value) {
6
+ return value == null || value === '';
7
+ },
8
+
9
+ /**
10
+ * @method when
11
+ * If an object is thenable, then return the object itself, otherwise wrap it into a promise
12
+ * @param {any}
13
+ * @deferred
14
+ */
15
+ when(param) {
16
+ if (param != null && _.isFunction(param.then)) {
17
+ return param;
18
+ // eslint-disable-next-line no-undefined
19
+ } else if (param !== undefined) {
20
+ return new Promise(function (resolve) {
21
+ resolve(param);
22
+ });
23
+ }
24
+ return new Promise(function (resolve, reject) {
25
+ reject();
26
+ });
27
+ }
28
+
29
+ };