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,113 @@
1
+ import * as winston from "winston";
2
+ import { ActionheroConfigInterface } from "..";
3
+
4
+ const namespace = "logger";
5
+
6
+ declare module ".." {
7
+ export interface ActionheroConfigInterface {
8
+ [namespace]: ReturnType<(typeof DEFAULT)[typeof namespace]>;
9
+ }
10
+ }
11
+
12
+ /*
13
+ The loggers defined here will eventually be available via `import { loggers } from "actionhero"`
14
+
15
+ You may want to customize how Actionhero sets the log level. By default, you can use `process.env.LOG_LEVEL` to change each logger's level (default: 'info')
16
+
17
+ learn more about winston v3 loggers @
18
+ - https://github.com/winstonjs/winston
19
+ - https://github.com/winstonjs/winston/blob/master/docs/transports.md
20
+ */
21
+
22
+ type ActionheroConfigLoggerBuilderArray = Array<
23
+ (config: ActionheroConfigInterface) => winston.Logger
24
+ >;
25
+
26
+ export const DEFAULT = {
27
+ [namespace]: (config: ActionheroConfigInterface) => {
28
+ const loggers: ActionheroConfigLoggerBuilderArray = [];
29
+ loggers.push(buildConsoleLogger(process.env.LOG_LEVEL));
30
+ config.general.paths.log.forEach((p: string) => {
31
+ loggers.push(buildFileLogger(p, process.env.LOG_LEVEL));
32
+ });
33
+
34
+ return {
35
+ loggers,
36
+ maxLogStringLength: 100, // the maximum length of param to log (we will truncate)
37
+ maxLogArrayLength: 10, // the maximum number of items in an array to log before collapsing into one message
38
+ };
39
+ },
40
+ };
41
+
42
+ export const test = {
43
+ [namespace]: (config: ActionheroConfigInterface) => {
44
+ const loggers: ActionheroConfigLoggerBuilderArray = [];
45
+ loggers.push(buildConsoleLogger(process.env.LOG_LEVEL ?? "crit"));
46
+ config.general.paths.log.forEach((path: string) => {
47
+ loggers.push(buildFileLogger(path, "debug", 1));
48
+ });
49
+
50
+ return { loggers };
51
+ },
52
+ };
53
+
54
+ // helpers for building the winston loggers
55
+
56
+ function buildConsoleLogger(level = "info") {
57
+ return function () {
58
+ return winston.createLogger({
59
+ format: winston.format.combine(
60
+ winston.format.timestamp(),
61
+ winston.format.colorize(),
62
+ winston.format.printf((info) => {
63
+ return `${info.timestamp} - ${info.level}: ${
64
+ info.message
65
+ } ${stringifyExtraMessagePropertiesForConsole(info)}`;
66
+ }),
67
+ ),
68
+ level,
69
+ levels: winston.config.syslog.levels,
70
+ transports: [new winston.transports.Console()],
71
+ });
72
+ };
73
+ }
74
+
75
+ function buildFileLogger(path: string, level = "info", maxFiles?: number) {
76
+ return function (config: ActionheroConfigInterface) {
77
+ const filename = `${path}/${config.process.id}-${config.process.env}.log`;
78
+ return winston.createLogger({
79
+ format: winston.format.combine(
80
+ winston.format.timestamp(),
81
+ winston.format.json(),
82
+ ),
83
+ level,
84
+ levels: winston.config.syslog.levels,
85
+ transports: [
86
+ new winston.transports.File({
87
+ filename,
88
+ maxFiles,
89
+ }),
90
+ ],
91
+ });
92
+ };
93
+ }
94
+
95
+ function stringifyExtraMessagePropertiesForConsole(
96
+ info: winston.Logform.TransformableInfo,
97
+ ) {
98
+ const skippedProperties = ["message", "timestamp", "level"];
99
+ let response = "";
100
+
101
+ for (const key in info) {
102
+ const value = info[key];
103
+ if (skippedProperties.includes(key)) {
104
+ continue;
105
+ }
106
+ if (value === undefined || value === null || value === "") {
107
+ continue;
108
+ }
109
+ response += `${key}=${value} `;
110
+ }
111
+
112
+ return response;
113
+ }
@@ -0,0 +1,37 @@
1
+ import { PluginConfig } from "..";
2
+
3
+ const namespace = "plugins";
4
+
5
+ declare module ".." {
6
+ export interface ActionheroConfigInterface {
7
+ [namespace]: ReturnType<(typeof DEFAULT)[typeof namespace]>;
8
+ }
9
+ }
10
+
11
+ export const DEFAULT: { [namespace]: () => PluginConfig } = {
12
+ [namespace]: () => {
13
+ /*
14
+ If you want to use plugins in your application, include them here:
15
+
16
+ return {
17
+ 'myPlugin': { path: __dirname + '/../node_modules/myPlugin' }
18
+ }
19
+
20
+ You can also toggle on or off sections of a plugin to include (default true for all sections):
21
+
22
+ return {
23
+ 'myPlugin': {
24
+ path: __dirname + '/../node_modules/myPlugin',
25
+ actions: true,
26
+ tasks: true,
27
+ initializers: true,
28
+ servers: true,
29
+ public: true,
30
+ cli: true
31
+ }
32
+ }
33
+ */
34
+
35
+ return {};
36
+ },
37
+ };
@@ -0,0 +1,78 @@
1
+ import { URL } from "url";
2
+
3
+ const namespace = "redis";
4
+
5
+ declare module ".." {
6
+ export interface ActionheroConfigInterface {
7
+ [namespace]: ReturnType<(typeof DEFAULT)[typeof namespace]>;
8
+ }
9
+ }
10
+
11
+ /**
12
+ * This is the standard redis config for Actionhero.
13
+ * This will use a redis server to persist cache, share chat message between processes, etc.
14
+ */
15
+
16
+ export const DEFAULT = {
17
+ [namespace]: () => {
18
+ const konstructor = require("ioredis"); // or konstructor = require("ioredis-mock") if you don't need real redis;
19
+ let protocol = process.env.REDIS_SSL ? "rediss" : "redis";
20
+ let host = process.env.REDIS_HOST || "127.0.0.1";
21
+ let port = process.env.REDIS_PORT || 6379;
22
+ let db = process.env.REDIS_DB || process.env.JEST_WORKER_ID || "0";
23
+ let password = process.env.REDIS_PASSWORD || null;
24
+
25
+ if (process.env.REDIS_URL) {
26
+ const parsed = new URL(process.env.REDIS_URL);
27
+ if (parsed.protocol) protocol = parsed.protocol.split(":")[0];
28
+ if (parsed.password) password = parsed.password;
29
+ if (parsed.hostname) host = parsed.hostname;
30
+ if (parsed.port) port = parsed.port;
31
+ if (parsed.pathname) db = parsed.pathname.substring(1);
32
+ }
33
+
34
+ const maxBackoff = 1000;
35
+ const commonArgs = {
36
+ port,
37
+ host,
38
+ password,
39
+ db: parseInt(db),
40
+ // ssl options
41
+ tls: protocol === "rediss" ? { rejectUnauthorized: false } : undefined,
42
+ // you can learn more about retryStrategy @ https://github.com/luin/ioredis#auto-reconnect
43
+ retryStrategy: (times: number) => {
44
+ if (times === 1) {
45
+ console.error(
46
+ "Unable to connect to Redis - please check your Redis config!",
47
+ );
48
+ return 5000;
49
+ }
50
+ return Math.min(times * 50, maxBackoff);
51
+ },
52
+ };
53
+
54
+ return {
55
+ // how many items should be fetched in a batch at once?
56
+ scanCount: 1000,
57
+ // how many ms should we wait when disconnecting after sending server-side disconnect message to the cluster
58
+ stopTimeout: 100,
59
+
60
+ _toExpand: false,
61
+ client: {
62
+ konstructor,
63
+ args: [commonArgs],
64
+ buildNew: true,
65
+ },
66
+ subscriber: {
67
+ konstructor,
68
+ args: [commonArgs],
69
+ buildNew: true,
70
+ },
71
+ tasks: {
72
+ konstructor,
73
+ args: [commonArgs],
74
+ buildNew: true,
75
+ },
76
+ };
77
+ },
78
+ };
@@ -0,0 +1,44 @@
1
+ import { RoutesConfig } from "..";
2
+
3
+ const namespace = "routes";
4
+
5
+ declare module ".." {
6
+ export interface ActionheroConfigInterface {
7
+ [namespace]: ReturnType<(typeof DEFAULT)[typeof namespace]>;
8
+ }
9
+ }
10
+
11
+ export const DEFAULT: { [namespace]: () => RoutesConfig } = {
12
+ [namespace]: () => {
13
+ return {
14
+ get: [
15
+ { path: "/status", action: "status" },
16
+ { path: "/swagger", action: "swagger" },
17
+ { path: "/createChatRoom", action: "createChatRoom" },
18
+ ],
19
+
20
+ /* ---------------------
21
+ For web clients (http and https) you can define an optional RESTful mapping to help route requests to actions.
22
+ If the client doesn't specify and action in a param, and the base route isn't a named action, the action will attempt to be discerned from this routes.js file.
23
+
24
+ Learn more here: https://www.actionherojs.com/tutorials/web-server#Routes
25
+
26
+ examples:
27
+
28
+ get: [
29
+ { path: '/users', action: 'usersList' }, // (GET) /api/users
30
+ { path: '/search/:term/limit/:limit/offset/:offset', action: 'search' }, // (GET) /api/search/car/limit/10/offset/100
31
+ ],
32
+
33
+ post: [
34
+ { path: '/login/:userID(^\\d{3}$)', action: 'login' } // (POST) /api/login/123
35
+ ],
36
+
37
+ all: [
38
+ { path: '/user/:userID', action: 'user', matchTrailingPathParts: true } // (*) /api/user/123, api/user/123/stuff
39
+ ]
40
+
41
+ ---------------------- */
42
+ };
43
+ },
44
+ };
@@ -0,0 +1,84 @@
1
+ import { ActionheroLogLevel } from "..";
2
+ import { MultiWorker, Queue, Scheduler } from "node-resque";
3
+
4
+ const namespace = "tasks";
5
+
6
+ declare module ".." {
7
+ export interface ActionheroConfigInterface {
8
+ [namespace]: ReturnType<(typeof DEFAULT)[typeof namespace]>;
9
+ }
10
+ }
11
+
12
+ export const DEFAULT = {
13
+ [namespace]: () => {
14
+ return {
15
+ _toExpand: false,
16
+
17
+ // Should this node run a scheduler to promote delayed tasks?
18
+ scheduler: false,
19
+
20
+ // what queues should the taskProcessors work?
21
+ queues: ["*"] as string[] | (() => Promise<string[]>),
22
+ // Or, rather than providing a static list of `queues`, you can define a method that returns the list of queues.
23
+ // queues: async () => { return ["queueA", "queueB"]; } as string[] | (() => Promise<string[]>)>,
24
+
25
+ // Logging levels of task workers
26
+ workerLogging: {
27
+ failure: "error" as ActionheroLogLevel, // task failure
28
+ success: "info" as ActionheroLogLevel, // task success
29
+ start: "info" as ActionheroLogLevel,
30
+ end: "info" as ActionheroLogLevel,
31
+ cleaning_worker: "info" as ActionheroLogLevel,
32
+ poll: "debug" as ActionheroLogLevel,
33
+ job: "debug" as ActionheroLogLevel,
34
+ pause: "debug" as ActionheroLogLevel,
35
+ reEnqueue: "debug" as ActionheroLogLevel,
36
+ internalError: "error" as ActionheroLogLevel,
37
+ multiWorkerAction: "debug" as ActionheroLogLevel,
38
+ },
39
+ // Logging levels of the task scheduler
40
+ schedulerLogging: {
41
+ start: "info" as ActionheroLogLevel,
42
+ end: "info" as ActionheroLogLevel,
43
+ poll: "debug" as ActionheroLogLevel,
44
+ enqueue: "debug" as ActionheroLogLevel,
45
+ working_timestamp: "debug" as ActionheroLogLevel,
46
+ reEnqueue: "debug" as ActionheroLogLevel,
47
+ transferred_job: "debug" as ActionheroLogLevel,
48
+ },
49
+ // how long to sleep between jobs / scheduler checks
50
+ timeout: 5000,
51
+ // at minimum, how many parallel taskProcessors should this node spawn?
52
+ // (have number > 0 to enable, and < 1 to disable)
53
+ minTaskProcessors: 0,
54
+ // at maximum, how many parallel taskProcessors should this node spawn?
55
+ maxTaskProcessors: 0,
56
+ // how often should we check the event loop to spawn more taskProcessors?
57
+ checkTimeout: 500,
58
+ // how many ms would constitute an event loop delay to halt taskProcessors spawning?
59
+ maxEventLoopDelay: 5,
60
+ // how long before we mark a resque worker / task processor as stuck/dead?
61
+ stuckWorkerTimeout: 1000 * 60 * 60,
62
+ // should the scheduler automatically try to retry failed tasks which were failed due to being 'stuck'?
63
+ retryStuckJobs: false,
64
+ // Customize Resque primitives, replace null with required replacement.
65
+ resque_overrides: {
66
+ queue: null as Queue,
67
+ multiWorker: null as MultiWorker,
68
+ scheduler: null as Scheduler,
69
+ },
70
+ connectionOptions: {
71
+ tasks: {},
72
+ },
73
+ };
74
+ },
75
+ };
76
+
77
+ export const test = {
78
+ [namespace]: () => {
79
+ return {
80
+ timeout: 100,
81
+ checkTimeout: 50,
82
+ };
83
+ },
84
+ };
@@ -0,0 +1,136 @@
1
+ import * as os from "os";
2
+ import { ActionheroConfigInterface } from "..";
3
+
4
+ import type { Options as FormParserOptions } from "formidable";
5
+
6
+ const namespace = "web";
7
+
8
+ declare module ".." {
9
+ export interface ActionheroConfigInterface {
10
+ [namespace]: ReturnType<(typeof DEFAULT)[typeof namespace]>;
11
+ }
12
+ }
13
+
14
+ export const DEFAULT = {
15
+ [namespace]: (config: ActionheroConfigInterface) => {
16
+ return {
17
+ enabled: true,
18
+ // HTTP or HTTPS? This setting is to enable SSL termination directly in the actionhero app, not set redirection host headers
19
+ secure: false,
20
+ // Passed to https.createServer if secure=true. Should contain SSL certificates
21
+ serverOptions: {},
22
+ // Should we redirect all traffic to the first host in this array if hte request header doesn't match?
23
+ // i.e.: [ 'https://www.site.com' ]
24
+ allowedRequestHosts: process.env.ALLOWED_HOSTS
25
+ ? process.env.ALLOWED_HOSTS.split(",")
26
+ : [],
27
+ // Port or Socket Path
28
+ port: process.env.PORT || 8080,
29
+ // Which IP to listen on (use '0.0.0.0' for the default ip stack; '::' for all on ipv4 and ipv6)
30
+ // Set to `null` when listening to socket
31
+ bindIP: "::",
32
+ // Any additional headers you want actionhero to respond with
33
+ httpHeaders: {
34
+ "X-Powered-By": config.general.serverName,
35
+ "Access-Control-Allow-Origin": "*",
36
+ "Access-Control-Allow-Methods":
37
+ "HEAD, GET, POST, PUT, PATCH, DELETE, OPTIONS, TRACE",
38
+ "Access-Control-Allow-Headers": "Content-Type",
39
+ "Strict-Transport-Security": "max-age=31536000; includeSubDomains",
40
+ },
41
+ // Route that actions will be served from; secondary route against this route will be treated as actions,
42
+ // IE: /api/?action=test == /api/test/
43
+ urlPathForActions: "api",
44
+ // Route that static files will be served from;
45
+ // path (relative to your project root) to serve static content from
46
+ // set to `null` to disable the file server entirely
47
+ urlPathForFiles: "public",
48
+ // When visiting the root URL, should visitors see 'api' or 'file'?
49
+ // Visitors can always visit /api and /public as normal
50
+ rootEndpointType: "file",
51
+ // In addition to what's defined in config/routes.ts, should we make a route for every action? Useful for debugging or simple APIs.
52
+ // automaticRoutes should an array of strings - HTTP verbs, ie: [] (default), ['get'], ['post'], ['get','put'], ['get','post','put'], etc.
53
+ automaticRoutes: process.env.AUTOMATIC_ROUTES
54
+ ? process.env.AUTOMATIC_ROUTES.split(",")
55
+ .map((v) => v.trim())
56
+ .map((v) => v.toLowerCase())
57
+ : [],
58
+ // Default HTTP status code for errors thrown in an action
59
+ defaultErrorStatusCode: 500,
60
+ // The cache or (if etags are enabled) next-revalidation time to be returned for all flat files served from /public; defined in seconds
61
+ flatFileCacheDuration: 60,
62
+ // Add an etag header to requested flat files which acts as fingerprint that changes when the file is updated;
63
+ // Client will revalidate the fingerprint at latest after flatFileCacheDuration and reload it if the etag (and therefore the file) changed
64
+ // or continue to use the cached file if it's still valid
65
+ enableEtag: true,
66
+ // should we save the un-parsed HTTP POST/PUT payload to connection.rawConnection.params.rawBody?
67
+ saveRawBody: false,
68
+ // How many times should we try to boot the server?
69
+ // This might happen if the port is in use by another process or the socket file is claimed
70
+ bootAttempts: 1,
71
+ // Settings for determining the id of an http(s) request (browser-fingerprint)
72
+ fingerprintOptions: {
73
+ cookieKey: "sessionID",
74
+ toSetCookie: true,
75
+ onlyStaticElements: false,
76
+ settings: {
77
+ path: "/",
78
+ expires: 3600000,
79
+ },
80
+ },
81
+ // Options to be applied to incoming file uploads.
82
+ // More options and details at https://github.com/felixge/node-formidable
83
+ formOptions: {
84
+ uploadDir: os.tmpdir(),
85
+ keepExtensions: false,
86
+ maxFieldsSize: 1024 * 1024 * 20,
87
+ maxFileSize: 1024 * 1024 * 200,
88
+ } as FormParserOptions,
89
+ // Should we pad JSON responses with whitespace to make them more human-readable?
90
+ // set to null to disable
91
+ padding: 2,
92
+ // Options to configure metadata in responses
93
+ metadataOptions: {
94
+ serverInformation: true,
95
+ requesterInformation: true,
96
+ },
97
+ // When true, returnErrorCodes will modify the response header for http(s) clients if connection.error is not null.
98
+ // You can also set connection.rawConnection.responseHttpCode to specify a code per request.
99
+ returnErrorCodes: true,
100
+ // should this node server attempt to gzip responses if the client can accept them?
101
+ // this will slow down the performance of actionhero, and if you need this functionality, it is recommended that you do this upstream with nginx or your load balancer
102
+ compress: false,
103
+ // options to pass to the query parser
104
+ // learn more about the options @ https://github.com/hapijs/qs
105
+ queryParseOptions: {},
106
+ };
107
+ },
108
+ };
109
+
110
+ export const production = {
111
+ [namespace]: () => {
112
+ return {
113
+ padding: null as number,
114
+ metadataOptions: {
115
+ serverInformation: false,
116
+ requesterInformation: false,
117
+ },
118
+ };
119
+ },
120
+ };
121
+
122
+ export const test = {
123
+ [namespace]: () => {
124
+ return {
125
+ secure: false,
126
+ port: process.env.PORT
127
+ ? process.env.PORT
128
+ : 18080 + parseInt(process.env.JEST_WORKER_ID || "0"),
129
+ matchExtensionMime: true,
130
+ metadataOptions: {
131
+ serverInformation: true,
132
+ requesterInformation: true,
133
+ },
134
+ };
135
+ },
136
+ };
@@ -0,0 +1,62 @@
1
+ // Note that to use the websocket server, you also need the web server enabled
2
+
3
+ import { ActionheroConfigInterface } from "..";
4
+
5
+ const namespace = "websocket";
6
+
7
+ declare module ".." {
8
+ export interface ActionheroConfigInterface {
9
+ [namespace]: ReturnType<(typeof DEFAULT)[typeof namespace]>;
10
+ }
11
+ }
12
+
13
+ export const DEFAULT = {
14
+ [namespace]: (config: ActionheroConfigInterface) => {
15
+ return {
16
+ enabled: true,
17
+ // you can pass a FQDN (like https://company.com) here or 'window.location.origin'
18
+ clientUrl: "window.location.origin",
19
+ // Directory to render client-side JS.
20
+ // Path should start with "/" and will be built starting from api.config..general.paths.public
21
+ clientJsPath: "javascript/",
22
+ // the name of the client-side JS file to render. Both `.js` and `.min.js` versions will be created
23
+ // do not include the file extension
24
+ // set to `undefined` to not render the client-side JS on boot
25
+ clientJsName: "ActionheroWebsocketClient",
26
+ // should the server signal clients to not reconnect when the server is shutdown/reboot
27
+ destroyClientsOnShutdown: false,
28
+
29
+ // websocket Server Options:
30
+ server: {
31
+ // authorization: null,
32
+ // pathname: '/primus',
33
+ // parser: 'JSON',
34
+ // transformer: 'websockets',
35
+ // plugin: {},
36
+ // timeout: 35000,
37
+ // origins: '*',
38
+ // methods: ['GET','HEAD','PUT','POST','DELETE','OPTIONS'],
39
+ // credentials: true,
40
+ // maxAge: '30 days',
41
+ // exposed: false,
42
+ },
43
+
44
+ // websocket Client Options:
45
+ client: {
46
+ apiPath: "/api", // the api base endpoint on your actionhero server
47
+ // the cookie name we should use for shared authentication between WS and web connections
48
+ cookieKey: config.web.fingerprintOptions.cookieKey,
49
+ // reconnect: {},
50
+ // timeout: 10000,
51
+ // ping: 25000,
52
+ // pong: 10000,
53
+ // strategy: "online",
54
+ // manual: false,
55
+ // websockets: true,
56
+ // network: true,
57
+ // transport: {},
58
+ // queueSize: Infinity,
59
+ },
60
+ };
61
+ },
62
+ };
package/src/index.ts ADDED
@@ -0,0 +1,46 @@
1
+ // export classes (capitalized)
2
+ export { Api } from "./classes/api";
3
+ export { Process } from "./classes/process";
4
+ export { ActionheroConfigInterface } from "./classes/config";
5
+ export { Initializer } from "./classes/initializer";
6
+ export { Connection } from "./classes/connection";
7
+ export { ExceptionReporter } from "./classes/exceptionReporter";
8
+ export { Action } from "./classes/action";
9
+ export { Task } from "./classes/task";
10
+ export { Server } from "./classes/server";
11
+ export { CLI } from "./classes/cli";
12
+ export { ActionProcessor } from "./classes/actionProcessor";
13
+ export { PluginConfig } from "./classes/config";
14
+ export { Inputs, ParamsFrom } from "./classes/inputs";
15
+ export { Input } from "./classes/input";
16
+
17
+ // export modules (lower case)
18
+ export { utils } from "./modules/utils";
19
+ export { config, rebuildConfig } from "./modules/config";
20
+ export { log, loggers, ActionheroLogLevel } from "./modules/log";
21
+ export { action } from "./modules/action";
22
+ export { task } from "./modules/task";
23
+ export { cache } from "./modules/cache";
24
+ export { chatRoom } from "./modules/chatRoom";
25
+ export { redis } from "./modules/redis";
26
+ export { route, RouteMethod, RouteType, RoutesConfig } from "./modules/route";
27
+ export { specHelper } from "./modules/specHelper";
28
+
29
+ // export static members of this process (lower case)
30
+ export { env } from "./classes/process/env";
31
+ export { actionheroVersion } from "./classes/process/actionheroVersion";
32
+ export { projectRoot } from "./classes/process/projectRoot";
33
+ export { typescript } from "./classes/process/typescript";
34
+ export { id } from "./classes/process/id";
35
+
36
+ // API object to hold connections, actions, tasks, initializers, and servers
37
+ import { Api } from "./classes/api";
38
+
39
+ // export a global API instance
40
+
41
+ declare module globalThis {
42
+ let api: Api;
43
+ }
44
+
45
+ if (!globalThis.api) globalThis.api = new Api();
46
+ export const api = globalThis.api;