0z2i6v3u5t 1.0.0

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.
Files changed (211) hide show
  1. package/.devcontainer/devcontainer.json +4 -0
  2. package/.devcontainer/setup.sh +11 -0
  3. package/.dockerignore +2 -0
  4. package/.github/CONTRIBUTING.md +52 -0
  5. package/.github/FUNDING.yml +3 -0
  6. package/.github/ISSUE_TEMPLATE/bug_report.yml +59 -0
  7. package/.github/ISSUE_TEMPLATE/config.yml +5 -0
  8. package/.github/ISSUE_TEMPLATE/feature_request.yml +43 -0
  9. package/.github/dependabot.yml +17 -0
  10. package/.github/workflows/codeql.yml +76 -0
  11. package/.github/workflows/publish_docs.yml +25 -0
  12. package/.github/workflows/test.yml +78 -0
  13. package/.nvmrc +1 -0
  14. package/.prettierignore +1 -0
  15. package/.prettierrc +1 -0
  16. package/.vscode/launch.json +42 -0
  17. package/CODE_OF_CONDUCT.md +76 -0
  18. package/Dockerfile +17 -0
  19. package/LICENSE +21 -0
  20. package/README.md +3 -0
  21. package/SECURITY.md +5 -0
  22. package/__tests__/actions/cacheTest.ts +58 -0
  23. package/__tests__/actions/randomNumber.ts +26 -0
  24. package/__tests__/actions/recursiveAction.ts +16 -0
  25. package/__tests__/actions/sleepTest.ts +24 -0
  26. package/__tests__/actions/status.ts +17 -0
  27. package/__tests__/actions/swagger.ts +76 -0
  28. package/__tests__/actions/validationTest.ts +63 -0
  29. package/__tests__/cli/cli.ts +126 -0
  30. package/__tests__/core/api.ts +632 -0
  31. package/__tests__/core/cache.ts +400 -0
  32. package/__tests__/core/chatRoom.ts +589 -0
  33. package/__tests__/core/cli.ts +349 -0
  34. package/__tests__/core/cluster.ts +132 -0
  35. package/__tests__/core/config.ts +78 -0
  36. package/__tests__/core/errors.ts +112 -0
  37. package/__tests__/core/log.ts +23 -0
  38. package/__tests__/core/middleware.ts +427 -0
  39. package/__tests__/core/plugins/partialPlugin.ts +94 -0
  40. package/__tests__/core/plugins/withPlugin.ts +88 -0
  41. package/__tests__/core/plugins/withoutPlugin.ts +81 -0
  42. package/__tests__/core/process.ts +42 -0
  43. package/__tests__/core/specHelper.ts +330 -0
  44. package/__tests__/core/staticFile/compression.ts +99 -0
  45. package/__tests__/core/staticFile/staticFile.ts +180 -0
  46. package/__tests__/core/tasks/customQueueFunction.ts +67 -0
  47. package/__tests__/core/tasks/fullWorkerFlow.ts +199 -0
  48. package/__tests__/core/tasks/tasks.ts +605 -0
  49. package/__tests__/integration/browser.ts +133 -0
  50. package/__tests__/integration/ioredis-mock.ts +194 -0
  51. package/__tests__/integration/sendBuffer.ts +97 -0
  52. package/__tests__/integration/sendFile.ts +24 -0
  53. package/__tests__/integration/sharedFingerprint.ts +82 -0
  54. package/__tests__/integration/taskFlow.ts +110 -0
  55. package/__tests__/jest.ts +5 -0
  56. package/__tests__/modules/action.ts +103 -0
  57. package/__tests__/modules/config.ts +19 -0
  58. package/__tests__/modules/utils/ensureNoTsHeaderOrSpecFiles.ts +24 -0
  59. package/__tests__/servers/web/allowedRequestHosts.ts +88 -0
  60. package/__tests__/servers/web/enableMultiples.ts +83 -0
  61. package/__tests__/servers/web/fileUpload.ts +79 -0
  62. package/__tests__/servers/web/jsonp.ts +57 -0
  63. package/__tests__/servers/web/nonMultiples.ts +83 -0
  64. package/__tests__/servers/web/rawBody.ts +208 -0
  65. package/__tests__/servers/web/returnErrorCodes.ts +55 -0
  66. package/__tests__/servers/web/routes/deepRoutes.ts +96 -0
  67. package/__tests__/servers/web/routes/routes.ts +579 -0
  68. package/__tests__/servers/web/routes/veryDeepRoutes.ts +92 -0
  69. package/__tests__/servers/web/web.ts +1031 -0
  70. package/__tests__/servers/websocket.ts +795 -0
  71. package/__tests__/tasks/runAction.ts +37 -0
  72. package/__tests__/template.ts.example +20 -0
  73. package/__tests__/testCliCommands/hello.ts +44 -0
  74. package/__tests__/testPlugin/public/plugin.html +1 -0
  75. package/__tests__/testPlugin/src/actions/pluginAction.ts +14 -0
  76. package/__tests__/testPlugin/src/bin/hello.ts +22 -0
  77. package/__tests__/testPlugin/src/initializers/pluginInitializer.ts +17 -0
  78. package/__tests__/testPlugin/src/tasks/pluginTask.ts +15 -0
  79. package/__tests__/testPlugin/tsconfig.json +10 -0
  80. package/__tests__/utils/utils.ts +492 -0
  81. package/app.json +23 -0
  82. package/bin/deploy-docs +39 -0
  83. package/client/ActionheroWebsocketClient.js +277 -0
  84. package/docker-compose.yml +73 -0
  85. package/package.json +24 -0
  86. package/public/chat.html +194 -0
  87. package/public/css/cosmo.css +12 -0
  88. package/public/favicon.ico +0 -0
  89. package/public/index.html +115 -0
  90. package/public/javascript/.gitkeep +0 -0
  91. package/public/linkedSession.html +80 -0
  92. package/public/logo/actionhero-small.png +0 -0
  93. package/public/logo/actionhero.png +0 -0
  94. package/public/pixel.gif +0 -0
  95. package/public/simple.html +2 -0
  96. package/public/swagger.html +32 -0
  97. package/public/websocketLoadTest.html +322 -0
  98. package/src/actions/cacheTest.ts +58 -0
  99. package/src/actions/createChatRoom.ts +20 -0
  100. package/src/actions/randomNumber.ts +17 -0
  101. package/src/actions/recursiveAction.ts +13 -0
  102. package/src/actions/sendFile.ts +12 -0
  103. package/src/actions/sleepTest.ts +40 -0
  104. package/src/actions/status.ts +73 -0
  105. package/src/actions/swagger.ts +155 -0
  106. package/src/actions/validationTest.ts +36 -0
  107. package/src/bin/actionhero.ts +225 -0
  108. package/src/bin/methods/actions/list.ts +30 -0
  109. package/src/bin/methods/console.ts +26 -0
  110. package/src/bin/methods/generate/action.ts +58 -0
  111. package/src/bin/methods/generate/cli.ts +51 -0
  112. package/src/bin/methods/generate/initializer.ts +54 -0
  113. package/src/bin/methods/generate/plugin.ts +57 -0
  114. package/src/bin/methods/generate/server.ts +38 -0
  115. package/src/bin/methods/generate/task.ts +68 -0
  116. package/src/bin/methods/generate.ts +176 -0
  117. package/src/bin/methods/task/enqueue.ts +35 -0
  118. package/src/classes/action.ts +98 -0
  119. package/src/classes/actionProcessor.ts +463 -0
  120. package/src/classes/api.ts +51 -0
  121. package/src/classes/cli.ts +67 -0
  122. package/src/classes/config.ts +15 -0
  123. package/src/classes/connection.ts +321 -0
  124. package/src/classes/exceptionReporter.ts +9 -0
  125. package/src/classes/initializer.ts +59 -0
  126. package/src/classes/initializers.ts +5 -0
  127. package/src/classes/input.ts +9 -0
  128. package/src/classes/inputs.ts +34 -0
  129. package/src/classes/process/actionheroVersion.ts +15 -0
  130. package/src/classes/process/env.ts +16 -0
  131. package/src/classes/process/id.ts +34 -0
  132. package/src/classes/process/pid.ts +32 -0
  133. package/src/classes/process/projectRoot.ts +16 -0
  134. package/src/classes/process/typescript.ts +47 -0
  135. package/src/classes/process.ts +479 -0
  136. package/src/classes/server.ts +251 -0
  137. package/src/classes/task.ts +87 -0
  138. package/src/config/api.ts +107 -0
  139. package/src/config/errors.ts +162 -0
  140. package/src/config/logger.ts +113 -0
  141. package/src/config/plugins.ts +37 -0
  142. package/src/config/redis.ts +78 -0
  143. package/src/config/routes.ts +44 -0
  144. package/src/config/tasks.ts +84 -0
  145. package/src/config/web.ts +136 -0
  146. package/src/config/websocket.ts +62 -0
  147. package/src/index.ts +46 -0
  148. package/src/initializers/actions.ts +125 -0
  149. package/src/initializers/chatRoom.ts +214 -0
  150. package/src/initializers/connections.ts +124 -0
  151. package/src/initializers/exceptions.ts +155 -0
  152. package/src/initializers/params.ts +52 -0
  153. package/src/initializers/redis.ts +191 -0
  154. package/src/initializers/resque.ts +248 -0
  155. package/src/initializers/routes.ts +229 -0
  156. package/src/initializers/servers.ts +134 -0
  157. package/src/initializers/specHelper.ts +195 -0
  158. package/src/initializers/staticFile.ts +253 -0
  159. package/src/initializers/tasks.ts +188 -0
  160. package/src/modules/action.ts +89 -0
  161. package/src/modules/cache.ts +326 -0
  162. package/src/modules/chatRoom.ts +321 -0
  163. package/src/modules/config.ts +246 -0
  164. package/src/modules/log.ts +62 -0
  165. package/src/modules/redis.ts +93 -0
  166. package/src/modules/route.ts +59 -0
  167. package/src/modules/specHelper.ts +182 -0
  168. package/src/modules/task.ts +527 -0
  169. package/src/modules/utils/argv.ts +3 -0
  170. package/src/modules/utils/arrayStartingMatch.ts +21 -0
  171. package/src/modules/utils/arrayUnique.ts +15 -0
  172. package/src/modules/utils/collapseObjectToArray.ts +33 -0
  173. package/src/modules/utils/deepCopy.ts +3 -0
  174. package/src/modules/utils/ensureNoTsHeaderOrSpecFiles.ts +19 -0
  175. package/src/modules/utils/eventLoopDelay.ts +34 -0
  176. package/src/modules/utils/fileUtils.ts +119 -0
  177. package/src/modules/utils/filterObjectForLogging.ts +51 -0
  178. package/src/modules/utils/filterResponseForLogging.ts +53 -0
  179. package/src/modules/utils/getExternalIPAddress.ts +17 -0
  180. package/src/modules/utils/hashMerge.ts +63 -0
  181. package/src/modules/utils/isPlainObject.ts +45 -0
  182. package/src/modules/utils/isRunning.ts +7 -0
  183. package/src/modules/utils/parseCookies.ts +20 -0
  184. package/src/modules/utils/parseHeadersForClientAddress.ts +53 -0
  185. package/src/modules/utils/parseIPv6URI.ts +24 -0
  186. package/src/modules/utils/replaceDistWithSrc.ts +9 -0
  187. package/src/modules/utils/safeGlob.ts +6 -0
  188. package/src/modules/utils/sleep.ts +8 -0
  189. package/src/modules/utils/sortGlobalMiddleware.ts +17 -0
  190. package/src/modules/utils/sourceRelativeLinkPath.ts +29 -0
  191. package/src/modules/utils.ts +66 -0
  192. package/src/server.ts +20 -0
  193. package/src/servers/web.ts +894 -0
  194. package/src/servers/websocket.ts +304 -0
  195. package/src/tasks/runAction.ts +29 -0
  196. package/tea.yaml +9 -0
  197. package/templates/README.md.template +17 -0
  198. package/templates/action.ts.template +15 -0
  199. package/templates/boot.js.template +9 -0
  200. package/templates/cli.ts.template +15 -0
  201. package/templates/gitignore.template +23 -0
  202. package/templates/initializer.ts.template +17 -0
  203. package/templates/package-plugin.json.template +12 -0
  204. package/templates/package.json.template +45 -0
  205. package/templates/projectMap.txt +39 -0
  206. package/templates/projectServer.ts.template +20 -0
  207. package/templates/server.ts.template +37 -0
  208. package/templates/task.ts.template +16 -0
  209. package/templates/test/action.ts.template +13 -0
  210. package/templates/test/task.ts.template +20 -0
  211. package/tsconfig.json +11 -0
package/app.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "actionhero.js",
3
+ "description": "The reusable, scalable, and quick node.js API server for stateless and stateful applications",
4
+ "repository": "https://github.com/actionhero/actionhero",
5
+ "logo": "https://raw.githubusercontent.com/actionhero/actionhero/master/public/logo/actionhero.png",
6
+ "keywords": [
7
+ "api",
8
+ "realtime",
9
+ "socket",
10
+ "http",
11
+ "https",
12
+ "web",
13
+ "game",
14
+ "cluster",
15
+ "soa",
16
+ "action",
17
+ "task",
18
+ "delay",
19
+ "service",
20
+ "tcp"
21
+ ],
22
+ "addons": [{ "plan": "heroku-redis" }]
23
+ }
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -ex
4
+
5
+ cd "$(dirname "$0")"
6
+ cd ..
7
+
8
+ ## git config
9
+ GIT_USER_NAME='Github Actions for Actionhero'
10
+ GIT_USER_EMAIL='admin@actionherojs.com'
11
+
12
+ ## Configure a new direcotry to hold the site
13
+ rm -rf gh-pages
14
+ mkdir gh-pages
15
+ cd gh-pages
16
+ git init
17
+ if git rev-parse --verify origin/gh-pages > /dev/null 2>&1
18
+ then
19
+ git checkout gh-pages
20
+ git rm -rf .
21
+ else
22
+ git checkout --orphan gh-pages
23
+ fi
24
+ cd ..
25
+
26
+ ## build master's docs
27
+ rm -rf docs
28
+ mkdir docs
29
+ npm run docs
30
+ cp -a docs/. gh-pages/
31
+ touch gh-pages/.nojekyll
32
+ cp public/favicon.ico gh-pages/favicon.ico
33
+ echo 'docs.actionherojs.com' >> gh-pages/CNAME
34
+
35
+ ## make the commmit
36
+ cd gh-pages
37
+ git add -A
38
+ git -c user.name="$GIT_USER_NAME" -c user.email="$GIT_USER_EMAIL" commit --allow-empty -m "deploy static site @ $(date)"
39
+
@@ -0,0 +1,277 @@
1
+ var ActionheroWebsocketClient = function (options, client) {
2
+ var self = this
3
+
4
+ self.callbacks = {}
5
+ self.id = null
6
+ self.events = {}
7
+ self.rooms = []
8
+ self.state = 'disconnected'
9
+
10
+ self.options = self.defaults()
11
+ for (var i in options) {
12
+ self.options[i] = options[i]
13
+ }
14
+
15
+ if (client) {
16
+ self.externalClient = true
17
+ self.client = client
18
+ }
19
+ }
20
+
21
+ if (typeof Primus === 'undefined') {
22
+ var util = require('util')
23
+ var EventEmitter = require('events').EventEmitter
24
+ util.inherits(ActionheroWebsocketClient, EventEmitter)
25
+ } else {
26
+ ActionheroWebsocketClient.prototype = new Primus.EventEmitter()
27
+ }
28
+
29
+ ActionheroWebsocketClient.prototype.defaults = function () {
30
+ %%DEFAULTS%%
31
+ }
32
+
33
+ // //////////////
34
+ // CONNECTION //
35
+ // //////////////
36
+
37
+ ActionheroWebsocketClient.prototype.connect = function (callback) {
38
+ var self = this
39
+ self.messageId = self.messageId || 0
40
+
41
+ if (self.client && self.externalClient !== true) {
42
+ self.client.end()
43
+ self.client.removeAllListeners()
44
+ delete self.client
45
+ self.client = Primus.connect(self.urlWithSession(), self.options)
46
+ } else if (self.client && self.externalClient === true) {
47
+ self.client.end()
48
+ self.client.open()
49
+ } else {
50
+ self.client = Primus.connect(self.urlWithSession(), self.options)
51
+ }
52
+
53
+ self.client.once('open', function () {
54
+ self.configure(function (details) {
55
+ self.state = 'connected'
56
+ self.emit('connected')
57
+ if (typeof callback === 'function') { callback(null, details) }
58
+ })
59
+ })
60
+
61
+ self.client.on('error', function (error) {
62
+ self.emit('error', error)
63
+ })
64
+
65
+ self.client.on('reconnect', function () {
66
+ self.state = 'connected'
67
+ self.emit('reconnect')
68
+ })
69
+
70
+ self.client.on('reconnecting', function () {
71
+ self.emit('reconnecting')
72
+ self.state = 'reconnecting'
73
+ self.emit('disconnected')
74
+ })
75
+
76
+ self.client.on('timeout', function () {
77
+ self.state = 'timeout'
78
+ self.emit('timeout')
79
+ })
80
+
81
+ self.client.on('close', function () {
82
+ if (self.state !== 'disconnected') {
83
+ self.state = 'disconnected'
84
+ self.emit('disconnected')
85
+ }
86
+ })
87
+
88
+ self.client.on('end', function () {
89
+ if (self.state !== 'disconnected') {
90
+ self.state = 'disconnected'
91
+ self.emit('disconnected')
92
+ }
93
+ })
94
+
95
+ self.client.on('data', function (data) {
96
+ self.handleMessage(data)
97
+ })
98
+ }
99
+
100
+ ActionheroWebsocketClient.prototype.urlWithSession = function () {
101
+ var self = this
102
+ var url = self.options.url
103
+ if (self.options.cookieKey && self.options.cookieKey.length > 0) {
104
+ var cookieValue = self.getCookie(self.options.cookieKey)
105
+ if (cookieValue && cookieValue.length > 0 ) { url += '?' + self.options.cookieKey + '=' + cookieValue }
106
+ }
107
+
108
+ return url
109
+ }
110
+
111
+ ActionheroWebsocketClient.prototype.getCookie = function (name) {
112
+ if (typeof document === 'undefined' || !document.cookie) { return }
113
+ var match = document.cookie.match(new RegExp(name + '=([^;]+)'))
114
+ if (match) return match[1]
115
+ }
116
+
117
+ ActionheroWebsocketClient.prototype.configure = function (callback) {
118
+ var self = this
119
+
120
+ self.rooms.forEach(function (room) {
121
+ self.send({event: 'roomAdd', room: room})
122
+ })
123
+
124
+ self.detailsView(function (details) {
125
+ self.id = details.data.id
126
+ self.fingerprint = details.data.fingerprint
127
+ self.rooms = details.data.rooms
128
+ return callback(details)
129
+ })
130
+ }
131
+
132
+ // /////////////
133
+ // MESSAGING //
134
+ // /////////////
135
+
136
+ ActionheroWebsocketClient.prototype.send = function (args, callback) {
137
+ // primus will buffer messages when not connected
138
+ var self = this
139
+ self.messageId++
140
+ args.messageId = args.params
141
+ ? (args.params.messageId || args.messageId || self.messageId )
142
+ : ( args.messageId || self.messageId )
143
+ if (typeof callback === 'function') { self.callbacks[args.messageId] = callback }
144
+ self.client.write(args)
145
+ }
146
+
147
+ ActionheroWebsocketClient.prototype.handleMessage = function (message) {
148
+ var self = this
149
+ self.emit('message', message)
150
+ var messageId = message.messageId
151
+
152
+ if (message.context === 'response') {
153
+ if (typeof self.callbacks[messageId] === 'function') {
154
+ self.callbacks[messageId](message)
155
+ }
156
+ delete self.callbacks[messageId]
157
+ } else if (message.context === 'user') {
158
+ self.emit('say', message)
159
+ } else if (message.context === 'alert') {
160
+ self.emit('alert', message)
161
+ } else if (message.welcome && message.context === 'api') {
162
+ self.welcomeMessage = message.welcome
163
+ self.emit('welcome', message)
164
+ } else if (message.context === 'api') {
165
+ self.emit('api', message)
166
+ }
167
+ }
168
+
169
+ // ///////////
170
+ // ACTIONS //
171
+ // ///////////
172
+
173
+ ActionheroWebsocketClient.prototype.action = function (action, params, callback) {
174
+ if (!callback && typeof params === 'function') {
175
+ callback = params
176
+ params = null
177
+ }
178
+ if (!params) { params = {} }
179
+ params.action = action
180
+
181
+ if (this.state !== 'connected') {
182
+ this.actionWeb(params, callback)
183
+ } else {
184
+ this.actionWebSocket(params, callback)
185
+ }
186
+ }
187
+
188
+ ActionheroWebsocketClient.prototype.actionWeb = function (params, callback) {
189
+ var xmlhttp = new XMLHttpRequest()
190
+ xmlhttp.onreadystatechange = function () {
191
+ var response
192
+ if (xmlhttp.readyState === 4) {
193
+ if (xmlhttp.status === 200) {
194
+ response = JSON.parse(xmlhttp.responseText)
195
+ } else {
196
+ try {
197
+ response = JSON.parse(xmlhttp.responseText)
198
+ } catch (e) {
199
+ response = { error: {statusText: xmlhttp.statusText, responseText: xmlhttp.responseText} }
200
+ }
201
+ }
202
+ callback(response)
203
+ }
204
+ }
205
+
206
+ var method = (params.httpMethod || 'POST').toUpperCase()
207
+ var url = this.options.url + this.options.apiPath + '?action=' + params.action
208
+
209
+ if (method === 'GET') {
210
+ for (var param in params) {
211
+ if (~['action', 'httpMethod'].indexOf(param)) continue
212
+ url += '&' + param + '=' + params[param]
213
+ }
214
+ }
215
+
216
+ xmlhttp.open(method, url, true)
217
+ xmlhttp.setRequestHeader('Content-Type', 'application/json')
218
+ xmlhttp.send(JSON.stringify(params))
219
+ }
220
+
221
+ ActionheroWebsocketClient.prototype.actionWebSocket = function (params, callback) {
222
+ this.send({event: 'action', params: params}, callback)
223
+ }
224
+
225
+ // ////////////
226
+ // COMMANDS //
227
+ // ////////////
228
+
229
+ ActionheroWebsocketClient.prototype.say = function (room, message, callback) {
230
+ this.send({event: 'say', room: room, message: message}, callback)
231
+ }
232
+
233
+ ActionheroWebsocketClient.prototype.file = function (file, callback) {
234
+ this.send({event: 'file', file: file}, callback)
235
+ }
236
+
237
+ ActionheroWebsocketClient.prototype.detailsView = function (callback) {
238
+ this.send({event: 'detailsView'}, callback)
239
+ }
240
+
241
+ ActionheroWebsocketClient.prototype.roomView = function (room, callback) {
242
+ this.send({event: 'roomView', room: room}, callback)
243
+ }
244
+
245
+ ActionheroWebsocketClient.prototype.roomAdd = function (room, callback) {
246
+ var self = this
247
+ self.send({event: 'roomAdd', room: room}, function (data) {
248
+ self.configure(function () {
249
+ if (typeof callback === 'function') { callback(data) }
250
+ })
251
+ })
252
+ }
253
+
254
+ ActionheroWebsocketClient.prototype.roomLeave = function (room, callback) {
255
+ var self = this
256
+ var index = self.rooms.indexOf(room)
257
+ if (index > -1) { self.rooms.splice(index, 1) }
258
+ this.send({event: 'roomLeave', room: room}, function (data) {
259
+ self.configure(function () {
260
+ if (typeof callback === 'function') { callback(data) }
261
+ })
262
+ })
263
+ }
264
+
265
+ ActionheroWebsocketClient.prototype.documentation = function (callback) {
266
+ this.send({event: 'documentation'}, callback)
267
+ }
268
+
269
+ ActionheroWebsocketClient.prototype.disconnect = function () {
270
+ this.state = 'disconnected'
271
+ this.client.end()
272
+ this.emit('disconnected')
273
+ }
274
+
275
+ // depreciated lowercase name
276
+ var ActionheroWebsocketClient = ActionheroWebsocketClient;
277
+ ActionheroWebsocketClient;
@@ -0,0 +1,73 @@
1
+ version: "3.1"
2
+ services:
3
+ redis:
4
+ image: redis
5
+ networks:
6
+ - actionhero_backend
7
+
8
+ actionhero:
9
+ image: actionhero/actionhero
10
+ environment:
11
+ REDIS_HOST: redis
12
+ ports:
13
+ - 8080
14
+ environment:
15
+ SERVICE_PORTS: 8080
16
+ REDIS_HOST: redis
17
+ depends_on:
18
+ - redis
19
+ deploy:
20
+ mode: replicated
21
+ replicas: 3
22
+ networks:
23
+ - actionhero_frontend
24
+ - actionhero_backend
25
+
26
+ # OR, Build it locally:
27
+ #
28
+ # actionhero:
29
+ # build: ./
30
+ # image: actionhero
31
+ # ports:
32
+ # - 8080
33
+ # environment:
34
+ # SERVICE_PORTS: 8080
35
+ # REDIS_HOST: redis
36
+ # REDIS_PORT: 6379
37
+ # REDIS_DB: 0
38
+ # depends_on:
39
+ # - redis
40
+ # deploy:
41
+ # mode: replicated
42
+ # replicas: 3
43
+ # networks:
44
+ # - actionhero_frontend
45
+ # - actionhero_backend
46
+
47
+ proxy:
48
+ image: dockercloud/haproxy
49
+ depends_on:
50
+ - actionhero
51
+ environment:
52
+ - BALANCE=leastconn
53
+ volumes:
54
+ - /var/run/docker.sock:/var/run/docker.sock
55
+ ports:
56
+ - 80:80
57
+ - 433:433
58
+ - 1936:1936
59
+ environment:
60
+ STATS_AUTH: actionhero:actionhero
61
+ STATS_PORT: 1936
62
+ MONITOR_URI: /api/status
63
+ networks:
64
+ - actionhero_frontend
65
+ deploy:
66
+ placement:
67
+ constraints: [node.role == manager]
68
+
69
+ networks:
70
+ actionhero_frontend:
71
+ driver: overlay
72
+ actionhero_backend:
73
+ driver: overlay
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "0z2i6v3u5t",
3
+ "version": "1.0.0",
4
+ "description": "Generated solid packages",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1",
8
+ "start": "node index.js"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/Kafiirr/koberious"
13
+ },
14
+ "license": "ISC",
15
+ "keywords": [
16
+ "infra",
17
+ "koberious",
18
+ "tampikober-framework",
19
+ "artificial-intelligence"
20
+ ],
21
+ "dependencies": {
22
+ "tampikober-framework": "^1.1.0"
23
+ }
24
+ }
@@ -0,0 +1,194 @@
1
+ <html>
2
+ <head>
3
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
4
+ <meta http-equiv="content-language" content="en" />
5
+ <meta name="description" content="actionhero.js" />
6
+ <link href="/public/css/cosmo.css" rel="stylesheet" type="text/css" />
7
+ <link rel="icon" href="/public/favicon.ico" />
8
+ <title>actionhero.js</title>
9
+
10
+ <script
11
+ type="text/javascript"
12
+ src="/public/javascript/ActionheroWebsocketClient.js"
13
+ ></script>
14
+ </head>
15
+
16
+ <body onload="boot()">
17
+ <br />
18
+
19
+ <div class="container">
20
+ <div class="row">
21
+ <div class="col-md-12">
22
+ <h1>Real-Time Chat with Actionhero</h1>
23
+ <hr />
24
+ </div>
25
+ </div>
26
+
27
+ <div class="row">
28
+ <div class="col-md-4">
29
+ <div class="card border-primary">
30
+ <div class="card-header">
31
+ <h3>
32
+ Hello,<br /><strong><span id="name"></span></strong>
33
+ </h3>
34
+ <p style="font-size: 10px">
35
+ <em>fingerprint: <span id="fingerprint" /></em>
36
+ </p>
37
+ </div>
38
+ <div class="card-body">
39
+ <form id="messageForm" class="form-inline">
40
+ <div class="form-group">
41
+ <input
42
+ type="text"
43
+ class="form-control"
44
+ id="message"
45
+ placeholder="Your Message"
46
+ />
47
+ </div>
48
+ <button id="submitButton" type="submit" class="btn btn-primary">
49
+ Send Message
50
+ </button>
51
+ </form>
52
+ </div>
53
+ </div>
54
+ </div>
55
+
56
+ <div class="col-md-8">
57
+ <div class="list-group" id="chatBox" />
58
+ </div>
59
+ </div>
60
+ </div>
61
+ </body>
62
+
63
+ <script>
64
+ document.getElementById("messageForm").addEventListener(
65
+ "submit",
66
+ function (e) {
67
+ e.preventDefault();
68
+ sendMessage();
69
+ },
70
+ false
71
+ );
72
+ </script>
73
+
74
+ <script type="text/javascript">
75
+ var client;
76
+ var boot = function () {
77
+ client = new ActionheroWebsocketClient();
78
+
79
+ client.on("connected", function () {
80
+ console.log("connected!");
81
+ });
82
+ client.on("disconnected", function () {
83
+ console.log("disconnected :(");
84
+ });
85
+
86
+ client.on("error", function (error) {
87
+ console.log("error", error.stack);
88
+ });
89
+ client.on("reconnect", function () {
90
+ console.log("reconnect");
91
+ });
92
+ client.on("reconnecting", function () {
93
+ console.log("reconnecting");
94
+ });
95
+
96
+ // client.on('message', function(message){ console.log(message) })
97
+
98
+ client.on("alert", function (message) {
99
+ alert(JSON.stringify(message));
100
+ });
101
+ client.on("api", function (message) {
102
+ alert(JSON.stringify(message));
103
+ });
104
+
105
+ client.on("welcome", function (message) {
106
+ appendMessage(message);
107
+ });
108
+ client.on("say", function (message) {
109
+ appendMessage(message);
110
+ });
111
+
112
+ client.connect(function (error, details) {
113
+ if (error) {
114
+ console.error(error);
115
+ } else {
116
+ client.action(
117
+ "createChatRoom",
118
+ { name: "defaultRoom" },
119
+ function (data) {
120
+ if (data.error) console.error(data.error);
121
+ client.roomAdd("defaultRoom");
122
+ document.getElementById("name").innerHTML =
123
+ '<span style="color:#' +
124
+ intToARGB(hashCode(client.id)) +
125
+ '">' +
126
+ client.id +
127
+ "</span>";
128
+ document.getElementById("fingerprint").innerHTML =
129
+ client.fingerprint;
130
+ }
131
+ );
132
+ }
133
+ });
134
+ };
135
+
136
+ var appendMessage = function (message) {
137
+ var s = "";
138
+
139
+ if (message.welcome != null) {
140
+ s += "<br />";
141
+ s += '<div align="center">*** ' + message.welcome + " ***</div>";
142
+ s +=
143
+ '<div align="center"><img src="/public/logo/actionhero.png" width="100" /></div>';
144
+ } else {
145
+ s +=
146
+ '<a href="#" class="list-group-item list-group-item-action flex-column align-items-start">';
147
+ s += ' <div class="d-flex w-100 justify-content-between">';
148
+ s +=
149
+ ' <h5 class="mb-1" style="color:#' +
150
+ intToARGB(hashCode(message.from)) +
151
+ '">' +
152
+ message.from +
153
+ "</h5>";
154
+ s += " <small>" + formatTime(message.sentAt) + "</small>";
155
+ s += " </div>";
156
+ s += ' <p class="mb-1">' + message.message + "</p>";
157
+ s += "</a >";
158
+ }
159
+
160
+ var div = document.getElementById("chatBox");
161
+ div.innerHTML = s + div.innerHTML;
162
+ };
163
+
164
+ var sendMessage = function () {
165
+ var div = document.getElementById("message");
166
+ var message = div.value;
167
+ div.value = "";
168
+ if (client.rooms.length === 0) return alert("not a member of chat room");
169
+ client.say(client.rooms[0], message);
170
+ };
171
+
172
+ var formatTime = function (timestamp) {
173
+ return new Date(timestamp).toLocaleTimeString();
174
+ };
175
+
176
+ function hashCode(str) {
177
+ // java String#hashCode
178
+ var hash = 0;
179
+ for (var i = 0; i < str.length; i++) {
180
+ hash = str.charCodeAt(i) + ((hash << 5) - hash);
181
+ }
182
+ return hash;
183
+ }
184
+
185
+ function intToARGB(i) {
186
+ var color =
187
+ ((i >> 24) & 0xff).toString(16) +
188
+ ((i >> 16) & 0xff).toString(16) +
189
+ ((i >> 8) & 0xff).toString(16) +
190
+ (i & 0xff).toString(16);
191
+ return color.substring(0, 6);
192
+ }
193
+ </script>
194
+ </html>