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
@@ -0,0 +1,304 @@
1
+ import * as Primus from "primus";
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ import * as util from "util";
5
+ import * as uuid from "uuid";
6
+ import { api, config, utils, log, Server, Connection } from "../index";
7
+
8
+ export class WebSocketServer extends Server {
9
+ server: Primus;
10
+
11
+ constructor() {
12
+ super();
13
+ this.type = "websocket";
14
+
15
+ this.attributes = {
16
+ canChat: true,
17
+ logConnections: true,
18
+ logExits: true,
19
+ sendWelcomeMessage: true,
20
+ verbs: [
21
+ "quit",
22
+ "exit",
23
+ "documentation",
24
+ "roomAdd",
25
+ "roomLeave",
26
+ "roomView",
27
+ "detailsView",
28
+ "say",
29
+ ],
30
+ };
31
+ }
32
+
33
+ async initialize() {
34
+ // we rely on the web server :D
35
+ }
36
+
37
+ async start() {
38
+ const webserver = api.servers.servers.web;
39
+ if (!webserver) {
40
+ throw new Error(`websocket server requires web server to be enabled`);
41
+ }
42
+
43
+ this.server = new Primus(webserver.server, this.config.server);
44
+
45
+ this.writeClientJS();
46
+
47
+ this.server.on("connection", (rawConnection) => {
48
+ this.handleConnection(rawConnection);
49
+ });
50
+
51
+ this.server.on("disconnection", (rawConnection) => {
52
+ this.handleDisconnection(rawConnection);
53
+ });
54
+
55
+ this.log(
56
+ `webSockets bound to ${webserver.config.bindIP}:${webserver.config.port}`,
57
+ "debug",
58
+ );
59
+
60
+ this.on("connection", (connection: Connection) => {
61
+ connection.rawConnection.on("data", (data: Record<string, any>) => {
62
+ this.handleData(connection, data);
63
+ });
64
+ });
65
+
66
+ this.on("actionComplete", (data) => {
67
+ if (data.toRender !== false) {
68
+ data.connection.response.messageId = data.messageId;
69
+ this.sendMessage(data.connection, data.response, data.messageId);
70
+ }
71
+ });
72
+ }
73
+
74
+ async stop() {
75
+ if (!this.server) return;
76
+
77
+ if (this.config.destroyClientsOnShutdown === true) {
78
+ this.connections().forEach((connection: Connection) => {
79
+ connection.destroy();
80
+ });
81
+ }
82
+
83
+ //@ts-ignore
84
+ this.server.destroy();
85
+ }
86
+
87
+ async sendMessage(
88
+ connection: Connection,
89
+ message: Record<string, any>,
90
+ messageId: string,
91
+ ) {
92
+ if (message.error) {
93
+ message.error = config.errors.serializers.servers.websocket(
94
+ message.error,
95
+ );
96
+ }
97
+
98
+ if (!message.context) {
99
+ message.context = "response";
100
+ }
101
+ if (!messageId) {
102
+ messageId = connection.messageId;
103
+ }
104
+ if (message.context === "response" && !message.messageId) {
105
+ message.messageId = messageId;
106
+ }
107
+
108
+ connection.rawConnection.write(message);
109
+ }
110
+
111
+ async sendFile(
112
+ connection: Connection,
113
+ error: NodeJS.ErrnoException,
114
+ fileStream: any,
115
+ mime: string,
116
+ length: number,
117
+ lastModified: Date,
118
+ ) {
119
+ const messageId = connection.messageId;
120
+ let content = "";
121
+ const response = {
122
+ error: error,
123
+ content: null as string,
124
+ mime: mime,
125
+ length: length,
126
+ lastModified: lastModified,
127
+ };
128
+
129
+ try {
130
+ if (!error) {
131
+ fileStream.on("data", (d: string) => {
132
+ content += d;
133
+ });
134
+ fileStream.on("end", () => {
135
+ response.content = content;
136
+ this.sendMessage(connection, response, messageId);
137
+ });
138
+ } else {
139
+ this.sendMessage(connection, response, messageId);
140
+ }
141
+ } catch (e) {
142
+ this.log(e, "warning");
143
+ this.sendMessage(connection, response, messageId);
144
+ }
145
+ }
146
+
147
+ //@ts-ignore
148
+ goodbye(connection: Connection) {
149
+ connection.rawConnection.end();
150
+ }
151
+
152
+ compileActionheroWebsocketClientJS() {
153
+ let ahClientSource = fs
154
+ .readFileSync(
155
+ path.join(__dirname, "/../../client/ActionheroWebsocketClient.js"),
156
+ )
157
+ .toString();
158
+ const url = this.config.clientUrl;
159
+ ahClientSource = ahClientSource.replace(/%%URL%%/g, url);
160
+ const defaults: {
161
+ [key: string]: any;
162
+ } = {};
163
+
164
+ for (const i in this.config.client) {
165
+ defaults[i] = this.config.client[i];
166
+ }
167
+
168
+ defaults.url = url;
169
+ let defaultsString = util.inspect(defaults);
170
+ defaultsString = defaultsString.replace(
171
+ "'window.location.origin'",
172
+ "window.location.origin",
173
+ );
174
+ ahClientSource = ahClientSource.replace(
175
+ "%%DEFAULTS%%",
176
+ "return " + defaultsString,
177
+ );
178
+
179
+ return ahClientSource;
180
+ }
181
+
182
+ renderClientJS() {
183
+ const libSource = api.servers.servers.websocket.server.library();
184
+ let ahClientSource = this.compileActionheroWebsocketClientJS();
185
+ ahClientSource =
186
+ ";;;\r\n" +
187
+ "(function(exports){ \r\n" +
188
+ ahClientSource +
189
+ "\r\n" +
190
+ "exports.ActionheroWebsocketClient = ActionheroWebsocketClient; \r\n" +
191
+ "exports.ActionheroWebsocketClient = ActionheroWebsocketClient; \r\n" +
192
+ "})(typeof exports === 'undefined' ? window : exports);";
193
+
194
+ return libSource + "\r\n\r\n\r\n" + ahClientSource;
195
+ }
196
+
197
+ writeClientJS() {
198
+ if (
199
+ !config.general.paths.public ||
200
+ config.general.paths.public.length === 0
201
+ ) {
202
+ return;
203
+ }
204
+
205
+ if (this.config.clientJsPath && this.config.clientJsName) {
206
+ const clientJSPath = path.normalize(
207
+ config.general.paths.public[0] +
208
+ path.sep +
209
+ this.config.clientJsPath +
210
+ path.sep,
211
+ );
212
+ const clientJSName = this.config.clientJsName;
213
+ const clientJSFullPath = clientJSPath + clientJSName;
214
+ try {
215
+ if (!fs.existsSync(clientJSPath)) {
216
+ fs.mkdirSync(clientJSPath, { recursive: true });
217
+ }
218
+ fs.writeFileSync(clientJSFullPath + ".js", this.renderClientJS());
219
+ log(`wrote ${clientJSFullPath}.js`, "debug");
220
+ } catch (e) {
221
+ log("Cannot write client-side JS for websocket server:", "alert", e);
222
+ throw e;
223
+ }
224
+ }
225
+ }
226
+
227
+ handleConnection(rawConnection: Primus.Spark) {
228
+ const fingerprint =
229
+ rawConnection.query[config.web.fingerprintOptions.cookieKey];
230
+ const { ip, port } = utils.parseHeadersForClientAddress(
231
+ rawConnection.headers,
232
+ );
233
+
234
+ this.buildConnection({
235
+ rawConnection: rawConnection,
236
+ remoteAddress: ip || rawConnection.address.ip,
237
+ remotePort: port || rawConnection.address.port,
238
+ fingerprint: fingerprint,
239
+ });
240
+ }
241
+
242
+ handleDisconnection(rawConnection: Primus.Spark) {
243
+ const connections = this.connections();
244
+ for (const i in connections) {
245
+ if (
246
+ connections[i] &&
247
+ rawConnection.id === connections[i].rawConnection.id
248
+ ) {
249
+ connections[i].destroy();
250
+ break;
251
+ }
252
+ }
253
+ }
254
+
255
+ async handleData(connection: Connection, data: Record<string, any>) {
256
+ const verb = data.event;
257
+ delete data.event;
258
+
259
+ connection.messageId = data.messageId || uuid.v4();
260
+ delete data.messageId;
261
+ connection.params = {};
262
+
263
+ if (verb === "action") {
264
+ for (const v in data.params) {
265
+ connection.params[v] = data.params[v];
266
+ }
267
+ connection.error = null;
268
+ connection.response = {};
269
+ return this.processAction(connection);
270
+ }
271
+
272
+ if (verb === "file") {
273
+ connection.params = {
274
+ file: data.file,
275
+ };
276
+ return this.processFile(connection);
277
+ }
278
+
279
+ const words = [];
280
+ let message;
281
+ if (data.room) {
282
+ words.push(data.room);
283
+ delete data.room;
284
+ }
285
+ for (const i in data) {
286
+ words.push(data[i]);
287
+ }
288
+ const messageId = connection.messageId;
289
+ try {
290
+ const data = await connection.verbs(verb, words);
291
+ message = { status: "OK", context: "response", data: data };
292
+ return this.sendMessage(connection, message, messageId);
293
+ } catch (error) {
294
+ const formattedError = error.toString();
295
+ message = {
296
+ status: formattedError,
297
+ error: formattedError,
298
+ context: "response",
299
+ data: data,
300
+ };
301
+ return this.sendMessage(connection, message, messageId);
302
+ }
303
+ }
304
+ }
@@ -0,0 +1,29 @@
1
+ import { log, Task, action, ParamsFrom } from "./../index";
2
+
3
+ export class RunAction extends Task {
4
+ name = "runAction";
5
+ description = "I will run an action and return the connection object";
6
+ frequency = 0;
7
+ queue = "default";
8
+
9
+ async run(params: ParamsFrom<RunAction>) {
10
+ if (!params) params = {};
11
+
12
+ const response = await action.run(
13
+ params.action,
14
+ params.version,
15
+ // @ts-ignore
16
+ params.params,
17
+ );
18
+
19
+ if (response.error) {
20
+ log("task error: " + response.error, "error", {
21
+ params: JSON.stringify(params),
22
+ });
23
+ } else {
24
+ log("[ action @ task ]", "debug", { params: JSON.stringify(params) });
25
+ }
26
+
27
+ return response;
28
+ }
29
+ }
package/tea.yaml ADDED
@@ -0,0 +1,9 @@
1
+ # https://tea.xyz/what-is-this-file
2
+ ---
3
+ version: 1.0.0
4
+ codeOwners:
5
+ - '0xa98810E2e6651F5bD3B6228a798e26C4e3C08862'
6
+ - '0x6EA07435C33111F3A2e8526da031391b209D2637'
7
+ - '0x3287b8E6A699fDdB844fD7bb5BB1B77bB4673c42'
8
+ - '0x18Ad36Faa96CadC9553675C8F67077FFa3f266c1'
9
+ quorum: 1
@@ -0,0 +1,17 @@
1
+ # My actionhero Project
2
+
3
+ _visit www.actionherojs.com for more information_
4
+
5
+ ## To install:
6
+
7
+ (assuming you have [node](http://nodejs.org/), [TypeScript](https://www.typescriptlang.org/), and NPM installed)
8
+
9
+ `npm install`
10
+
11
+ ## To Run:
12
+
13
+ `npm start`
14
+
15
+ ## To Test:
16
+
17
+ `npm test`
@@ -0,0 +1,15 @@
1
+ import { Action } from "actionhero";
2
+
3
+ export class MyAction extends Action {
4
+ constructor() {
5
+ super();
6
+ this.name = "%%name%%";
7
+ this.description = "%%description%%";
8
+ this.outputExample = {};
9
+ }
10
+
11
+ async run(data) {
12
+ // your logic here
13
+ data.response.ok = true;
14
+ }
15
+ }
@@ -0,0 +1,9 @@
1
+ /* This file will load, be required, first in the actionhero binary.
2
+ Anything that needed loaded or run BEFORE actionhero starts can be done here.
3
+
4
+ This file returns a single method that is run immediately after loading.
5
+ */
6
+
7
+ // include high-level requires here.
8
+
9
+ exports.default = async function BOOT() {}
@@ -0,0 +1,15 @@
1
+ import { CLI } from "actionhero";
2
+
3
+ export class MyCLICommand extends CLI {
4
+ constructor() {
5
+ super();
6
+ this.name = "%%name%%";
7
+ this.description = "%%description%%";
8
+ this.example = "%%example%%";
9
+ this.inputs = {};
10
+ }
11
+
12
+ async run(data) {
13
+ return true;
14
+ }
15
+ }
@@ -0,0 +1,23 @@
1
+ # Actionhero files
2
+ pids/*
3
+ tmp/*
4
+ log/*
5
+ cache/*
6
+ coverage/*
7
+ node_modules/*
8
+ public/javascript/ActionheroWebsocketClient.js
9
+ dist
10
+
11
+ # Node / NPM
12
+ npm-debug.log
13
+
14
+ # OS-specific weirdness
15
+ .DS_Store
16
+
17
+ # Redis
18
+ dump.rdb
19
+ cache.dump
20
+
21
+ # Editor-specific
22
+ /nbproject/*
23
+ /.idea/*
@@ -0,0 +1,17 @@
1
+ import { Initializer } from "actionhero";
2
+
3
+ export class MyInitializer extends Initializer {
4
+ constructor() {
5
+ super();
6
+ this.name = "%%name%%";
7
+ this.loadPriority = %%loadPriority%%;
8
+ this.startPriority = %%startPriority%%;
9
+ this.stopPriority = %%stopPriority%%;
10
+ }
11
+
12
+ async initialize() {}
13
+
14
+ async start() {}
15
+
16
+ async stop() {}
17
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "author": "YOU <YOU@example.com>",
3
+ "name": "my_actionhero_plugin",
4
+ "description": "my actionhero plugin",
5
+ "version": "0.1.0",
6
+ "engines": {
7
+ "node": ">=8.0.0"
8
+ },
9
+ "peerDependencies": {
10
+ "actionhero": "%%versionNumber%%"
11
+ }
12
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "author": "YOU <YOU@example.com>",
3
+ "name": "my_actionhero_project",
4
+ "description": "my actionhero project",
5
+ "version": "0.1.0",
6
+ "engines": {
7
+ "node": ">=8.0.0"
8
+ },
9
+ "dependencies": {
10
+ "actionhero": "%%versionNumber%%",
11
+ "ws": "latest",
12
+ "ioredis": "latest",
13
+ "ioredis-mock": "latest",
14
+ "winston": "latest"
15
+ },
16
+ "devDependencies": {
17
+ "@types/node": "latest",
18
+ "@types/glob": "latest",
19
+ "@types/jest": "latest",
20
+ "jest": "latest",
21
+ "prettier": "latest",
22
+ "ts-jest": "latest",
23
+ "ts-node-dev": "latest",
24
+ "type-fest": "latest",
25
+ "typescript": "latest"
26
+ },
27
+ "scripts": {
28
+ "postinstall": "npm run build",
29
+ "dev": "ts-node-dev --no-deps --transpile-only ./src/server",
30
+ "debug": "tsc && ts-node-dev --transpile-only --no-deps --inspect -- ./src/server ",
31
+ "start": "node ./dist/server.js",
32
+ "actionhero": "actionhero",
33
+ "test": "jest",
34
+ "pretest": "npm run build && npm run lint",
35
+ "build": "tsc --sourceMap false --declaration",
36
+ "lint": "prettier --check src/*/** __tests__/*/**",
37
+ "pretty": "prettier --write src/*/** __tests__/*/**"
38
+ },
39
+ "jest": {
40
+ "testEnvironment": "node",
41
+ "transform": {
42
+ "^.+\\.ts?$": "ts-jest"
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,39 @@
1
+ |
2
+ |- src
3
+ | - server.ts
4
+ |
5
+ | - config
6
+ | - (project settings)
7
+ |
8
+ | - actions
9
+ | -- (your actions)
10
+ |
11
+ | - initializers
12
+ | -- (any additional initializers you want)
13
+ |
14
+ | - servers
15
+ | -- (custom servers you may make)
16
+ |
17
+ | - tasks
18
+ | -- (your tasks)
19
+ |
20
+ | - bin
21
+ | -- (your custom CLI commands)
22
+ |
23
+ |- __tests__
24
+ |-- (tests for your API)
25
+ |
26
+ | - log
27
+ |-- (default location for logs)
28
+ |
29
+ |- node_modules
30
+ |-- (your modules, actionhero should be npm installed in here)
31
+ |
32
+ |- pids
33
+ |-- (pidfiles for your running servers)
34
+ |
35
+ |- public
36
+ |-- (your static assets to be served by /file)
37
+ |
38
+ readme.md
39
+ package.json
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+
3
+ // load any custom code, configure the env, as needed
4
+
5
+ async function main() {
6
+ // create a new actionhero process
7
+ const { Process } = await import("actionhero");
8
+ const app = new Process();
9
+
10
+ // handle unix signals and uncaught exceptions & rejections
11
+ app.registerProcessSignals((exitCode) => {
12
+ process.exit(exitCode);
13
+ });
14
+
15
+ // start the app!
16
+ // you can pass custom configuration to the process as needed
17
+ await app.start();
18
+ }
19
+
20
+ main();
@@ -0,0 +1,37 @@
1
+ import { Server } from "actionhero";
2
+
3
+ export class MyServer extends Server {
4
+ constructor() {
5
+ super();
6
+ this.type = "%%name%%";
7
+
8
+ this.attributes = {
9
+ canChat: false,
10
+ logConnections: true,
11
+ logExits: true,
12
+ sendWelcomeMessage: false,
13
+ verbs: []
14
+ };
15
+ // this.config will be set to equal config[this.type]
16
+ }
17
+
18
+ async initialize() {
19
+ this.on("connection", connection => {});
20
+
21
+ this.on("actionComplete", data => {});
22
+ }
23
+
24
+ async start() {
25
+ // this.buildConnection (data)
26
+ // this.processAction (connection)
27
+ // this.processFile (connection)
28
+ }
29
+
30
+ async stop() {}
31
+
32
+ async sendMessage(connection, message, messageId) {}
33
+
34
+ async sendFile(connection, error, fileStream, mime, length, lastModified) {}
35
+
36
+ goodbye(connection) {}
37
+ }
@@ -0,0 +1,16 @@
1
+ import { Task } from "actionhero";
2
+
3
+ export class MyTask extends Task {
4
+ constructor() {
5
+ super();
6
+ this.name = "%%name%%";
7
+ this.description = "%%description%%";
8
+ this.frequency = %%frequency%%;
9
+ this.queue = "%%queue%%";
10
+ this.middleware = [];
11
+ }
12
+
13
+ async run(data) {
14
+ // your logic here
15
+ }
16
+ }
@@ -0,0 +1,13 @@
1
+ import { Process, specHelper } from "actionhero";
2
+
3
+ describe("Action: %%name%%", () => {
4
+ const actionhero = new Process();
5
+
6
+ beforeAll(async () => await actionhero.start());
7
+ afterAll(async () => await actionhero.stop());
8
+
9
+ test("returns OK", async () => {
10
+ const { ok } = await specHelper.runAction("%%name%%");
11
+ expect(ok).toEqual(true);
12
+ });
13
+ });
@@ -0,0 +1,20 @@
1
+ import { Process, task, api, specHelper } from "actionhero";
2
+
3
+ describe("Task: %%name%%", () => {
4
+ const actionhero = new Process();
5
+
6
+ beforeAll(async () => await actionhero.start());
7
+ afterAll(async () => await actionhero.stop());
8
+
9
+ beforeEach(async () => {
10
+ await api.resque.queue.connection.redis.flushdb();
11
+ });
12
+
13
+ test("can be enqueued", async () => {
14
+ await task.enqueue("%%name%%", {});
15
+ const found = await specHelper.findEnqueuedTasks("%%name%%");
16
+ expect(found.length).toEqual(1);
17
+ expect(found[0].timestamp).toBeNull();
18
+ });
19
+ });
20
+
package/tsconfig.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "compilerOptions": {
3
+ "outDir": "./dist",
4
+ "allowJs": true,
5
+ "module": "commonjs",
6
+ "target": "es2018",
7
+ "sourceMap": true,
8
+ "noImplicitAny": true
9
+ },
10
+ "include": ["./src/**/*"]
11
+ }