hotstaq 0.5.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.
Files changed (318) hide show
  1. package/.dockerignore +123 -0
  2. package/.eslintignore +17 -0
  3. package/.eslintrc.js +11 -0
  4. package/.vscode/launch.json +201 -0
  5. package/.vscode/settings.json +2 -0
  6. package/.vscode/tasks.json +88 -0
  7. package/CONTRIBUTING.md +157 -0
  8. package/LICENSE +21 -0
  9. package/README.md +128 -0
  10. package/bin/hotstaq +3 -0
  11. package/bin/hotstaq.cmd +1 -0
  12. package/build/src/Hot.d.ts +167 -0
  13. package/build/src/Hot.d.ts.map +1 -0
  14. package/build/src/Hot.js +365 -0
  15. package/build/src/Hot.js.map +1 -0
  16. package/build/src/HotAPI.d.ts +137 -0
  17. package/build/src/HotAPI.d.ts.map +1 -0
  18. package/build/src/HotAPI.js +353 -0
  19. package/build/src/HotAPI.js.map +1 -0
  20. package/build/src/HotAgentAPI.d.ts +22 -0
  21. package/build/src/HotAgentAPI.d.ts.map +1 -0
  22. package/build/src/HotAgentAPI.js +85 -0
  23. package/build/src/HotAgentAPI.js.map +1 -0
  24. package/build/src/HotAgentRoute.d.ts +17 -0
  25. package/build/src/HotAgentRoute.d.ts.map +1 -0
  26. package/build/src/HotAgentRoute.js +109 -0
  27. package/build/src/HotAgentRoute.js.map +1 -0
  28. package/build/src/HotBuilder.d.ts +52 -0
  29. package/build/src/HotBuilder.d.ts.map +1 -0
  30. package/build/src/HotBuilder.js +242 -0
  31. package/build/src/HotBuilder.js.map +1 -0
  32. package/build/src/HotClient.d.ts +31 -0
  33. package/build/src/HotClient.d.ts.map +1 -0
  34. package/build/src/HotClient.js +19 -0
  35. package/build/src/HotClient.js.map +1 -0
  36. package/build/src/HotComponent.d.ts +118 -0
  37. package/build/src/HotComponent.d.ts.map +1 -0
  38. package/build/src/HotComponent.js +89 -0
  39. package/build/src/HotComponent.js.map +1 -0
  40. package/build/src/HotCreator.d.ts +88 -0
  41. package/build/src/HotCreator.d.ts.map +1 -0
  42. package/build/src/HotCreator.js +445 -0
  43. package/build/src/HotCreator.js.map +1 -0
  44. package/build/src/HotDB.d.ts +69 -0
  45. package/build/src/HotDB.d.ts.map +1 -0
  46. package/build/src/HotDB.js +29 -0
  47. package/build/src/HotDB.js.map +1 -0
  48. package/build/src/HotDBConnectionInterface.d.ts +40 -0
  49. package/build/src/HotDBConnectionInterface.d.ts.map +1 -0
  50. package/build/src/HotDBConnectionInterface.js +3 -0
  51. package/build/src/HotDBConnectionInterface.js.map +1 -0
  52. package/build/src/HotFile.d.ts +134 -0
  53. package/build/src/HotFile.d.ts.map +1 -0
  54. package/build/src/HotFile.js +454 -0
  55. package/build/src/HotFile.js.map +1 -0
  56. package/build/src/HotGenerator.d.ts +80 -0
  57. package/build/src/HotGenerator.d.ts.map +1 -0
  58. package/build/src/HotGenerator.js +342 -0
  59. package/build/src/HotGenerator.js.map +1 -0
  60. package/build/src/HotHTTPServer.d.ts +162 -0
  61. package/build/src/HotHTTPServer.d.ts.map +1 -0
  62. package/build/src/HotHTTPServer.js +863 -0
  63. package/build/src/HotHTTPServer.js.map +1 -0
  64. package/build/src/HotIO.d.ts +47 -0
  65. package/build/src/HotIO.d.ts.map +1 -0
  66. package/build/src/HotIO.js +232 -0
  67. package/build/src/HotIO.js.map +1 -0
  68. package/build/src/HotLog.d.ts +60 -0
  69. package/build/src/HotLog.d.ts.map +1 -0
  70. package/build/src/HotLog.js +126 -0
  71. package/build/src/HotLog.js.map +1 -0
  72. package/build/src/HotPage.d.ts +125 -0
  73. package/build/src/HotPage.d.ts.map +1 -0
  74. package/build/src/HotPage.js +178 -0
  75. package/build/src/HotPage.js.map +1 -0
  76. package/build/src/HotRoute.d.ts +82 -0
  77. package/build/src/HotRoute.d.ts.map +1 -0
  78. package/build/src/HotRoute.js +83 -0
  79. package/build/src/HotRoute.js.map +1 -0
  80. package/build/src/HotRouteMethod.d.ts +129 -0
  81. package/build/src/HotRouteMethod.d.ts.map +1 -0
  82. package/build/src/HotRouteMethod.js +84 -0
  83. package/build/src/HotRouteMethod.js.map +1 -0
  84. package/build/src/HotServer.d.ts +152 -0
  85. package/build/src/HotServer.d.ts.map +1 -0
  86. package/build/src/HotServer.js +109 -0
  87. package/build/src/HotServer.js.map +1 -0
  88. package/build/src/HotSetAsWeb.d.ts +2 -0
  89. package/build/src/HotSetAsWeb.d.ts.map +1 -0
  90. package/build/src/HotSetAsWeb.js +5 -0
  91. package/build/src/HotSetAsWeb.js.map +1 -0
  92. package/build/src/HotStaq.d.ts +603 -0
  93. package/build/src/HotStaq.d.ts.map +1 -0
  94. package/build/src/HotStaq.js +1260 -0
  95. package/build/src/HotStaq.js.map +1 -0
  96. package/build/src/HotStaqWeb.d.ts +18 -0
  97. package/build/src/HotStaqWeb.d.ts.map +1 -0
  98. package/build/src/HotStaqWeb.js +44 -0
  99. package/build/src/HotStaqWeb.js.map +1 -0
  100. package/build/src/HotTestDriver.d.ts +63 -0
  101. package/build/src/HotTestDriver.d.ts.map +1 -0
  102. package/build/src/HotTestDriver.js +187 -0
  103. package/build/src/HotTestDriver.js.map +1 -0
  104. package/build/src/HotTestElement.d.ts +71 -0
  105. package/build/src/HotTestElement.d.ts.map +1 -0
  106. package/build/src/HotTestElement.js +37 -0
  107. package/build/src/HotTestElement.js.map +1 -0
  108. package/build/src/HotTestMap.d.ts +83 -0
  109. package/build/src/HotTestMap.d.ts.map +1 -0
  110. package/build/src/HotTestMap.js +58 -0
  111. package/build/src/HotTestMap.js.map +1 -0
  112. package/build/src/HotTestSeleniumDriver.d.ts +86 -0
  113. package/build/src/HotTestSeleniumDriver.d.ts.map +1 -0
  114. package/build/src/HotTestSeleniumDriver.js +400 -0
  115. package/build/src/HotTestSeleniumDriver.js.map +1 -0
  116. package/build/src/HotTester.d.ts +188 -0
  117. package/build/src/HotTester.d.ts.map +1 -0
  118. package/build/src/HotTester.js +622 -0
  119. package/build/src/HotTester.js.map +1 -0
  120. package/build/src/HotTesterAPI.d.ts +15 -0
  121. package/build/src/HotTesterAPI.d.ts.map +1 -0
  122. package/build/src/HotTesterAPI.js +161 -0
  123. package/build/src/HotTesterAPI.js.map +1 -0
  124. package/build/src/HotTesterMocha.d.ts +50 -0
  125. package/build/src/HotTesterMocha.d.ts.map +1 -0
  126. package/build/src/HotTesterMocha.js +205 -0
  127. package/build/src/HotTesterMocha.js.map +1 -0
  128. package/build/src/HotTesterMochaSelenium.d.ts +70 -0
  129. package/build/src/HotTesterMochaSelenium.d.ts.map +1 -0
  130. package/build/src/HotTesterMochaSelenium.js +257 -0
  131. package/build/src/HotTesterMochaSelenium.js.map +1 -0
  132. package/build/src/HotTesterServer.d.ts +114 -0
  133. package/build/src/HotTesterServer.d.ts.map +1 -0
  134. package/build/src/HotTesterServer.js +575 -0
  135. package/build/src/HotTesterServer.js.map +1 -0
  136. package/build/src/api copy.d.ts +2 -0
  137. package/build/src/api copy.d.ts.map +1 -0
  138. package/build/src/api copy.js +153 -0
  139. package/build/src/api copy.js.map +1 -0
  140. package/build/src/api-web.d.ts +2 -0
  141. package/build/src/api-web.d.ts.map +1 -0
  142. package/build/src/api-web.js +45 -0
  143. package/build/src/api-web.js.map +1 -0
  144. package/build/src/api.d.ts +33 -0
  145. package/build/src/api.d.ts.map +1 -0
  146. package/build/src/api.js +78 -0
  147. package/build/src/api.js.map +1 -0
  148. package/build/src/cli.d.ts +2 -0
  149. package/build/src/cli.d.ts.map +1 -0
  150. package/build/src/cli.js +1040 -0
  151. package/build/src/cli.js.map +1 -0
  152. package/build/src/schemas/HotDBInflux.d.ts +63 -0
  153. package/build/src/schemas/HotDBInflux.d.ts.map +1 -0
  154. package/build/src/schemas/HotDBInflux.js +239 -0
  155. package/build/src/schemas/HotDBInflux.js.map +1 -0
  156. package/build/src/schemas/HotDBMigration.d.ts +19 -0
  157. package/build/src/schemas/HotDBMigration.d.ts.map +1 -0
  158. package/build/src/schemas/HotDBMigration.js +15 -0
  159. package/build/src/schemas/HotDBMigration.js.map +1 -0
  160. package/build/src/schemas/HotDBMySQL.d.ts +65 -0
  161. package/build/src/schemas/HotDBMySQL.d.ts.map +1 -0
  162. package/build/src/schemas/HotDBMySQL.js +387 -0
  163. package/build/src/schemas/HotDBMySQL.js.map +1 -0
  164. package/build/src/schemas/HotDBSchema.d.ts +15 -0
  165. package/build/src/schemas/HotDBSchema.d.ts.map +1 -0
  166. package/build/src/schemas/HotDBSchema.js +19 -0
  167. package/build/src/schemas/HotDBSchema.js.map +1 -0
  168. package/build/src/schemas/influx/InfluxSchema.d.ts +14 -0
  169. package/build/src/schemas/influx/InfluxSchema.d.ts.map +1 -0
  170. package/build/src/schemas/influx/InfluxSchema.js +33 -0
  171. package/build/src/schemas/influx/InfluxSchema.js.map +1 -0
  172. package/build/src/schemas/mysql/MySQLSchema.d.ts +39 -0
  173. package/build/src/schemas/mysql/MySQLSchema.d.ts.map +1 -0
  174. package/build/src/schemas/mysql/MySQLSchema.js +151 -0
  175. package/build/src/schemas/mysql/MySQLSchema.js.map +1 -0
  176. package/build/src/schemas/mysql/MySQLSchemaField.d.ts +168 -0
  177. package/build/src/schemas/mysql/MySQLSchemaField.d.ts.map +1 -0
  178. package/build/src/schemas/mysql/MySQLSchemaField.js +260 -0
  179. package/build/src/schemas/mysql/MySQLSchemaField.js.map +1 -0
  180. package/build/src/schemas/mysql/MySQLSchemaTable.d.ts +49 -0
  181. package/build/src/schemas/mysql/MySQLSchemaTable.d.ts.map +1 -0
  182. package/build/src/schemas/mysql/MySQLSchemaTable.js +310 -0
  183. package/build/src/schemas/mysql/MySQLSchemaTable.js.map +1 -0
  184. package/build-web/HotStaq.js +2 -0
  185. package/build-web/HotStaq.min.js +119 -0
  186. package/build-web/HotStaqTests_HelloWorldAPI.js +133 -0
  187. package/builder/docker/Dockerfile.linux.gen +42 -0
  188. package/builder/docker/README.md +36 -0
  189. package/builder/docker/app/start.sh +8 -0
  190. package/builder/docker/dockerignore +3 -0
  191. package/builder/docker/scripts/build.bat +11 -0
  192. package/builder/docker/scripts/build.sh +11 -0
  193. package/builder/docker/scripts/start-app.bat +7 -0
  194. package/builder/docker/scripts/start-app.sh +7 -0
  195. package/builder/docker/scripts/stop-app.bat +5 -0
  196. package/builder/docker/scripts/stop-app.sh +5 -0
  197. package/builder/docker-compose/docker-compose.gen.yaml +41 -0
  198. package/builder/docker-compose/env-skeleton +4 -0
  199. package/creator/project/.vscode/launch.json +59 -0
  200. package/creator/project/README.md +20 -0
  201. package/creator/project/gitignore +118 -0
  202. package/creator/project/npmignore +118 -0
  203. package/creator/public/api-test.hott +28 -0
  204. package/creator/public/index.hott +12 -0
  205. package/creator/ts/src/AppAPI.ts +30 -0
  206. package/creator/ts/src/HelloWorld.ts +39 -0
  207. package/creator/ts/src/WebExport.ts +7 -0
  208. package/creator/ts/tsconfig-web.json +73 -0
  209. package/creator/ts/tsconfig.json +73 -0
  210. package/creator/ts/webpack-api.config.js +57 -0
  211. package/dbstart.sh +19 -0
  212. package/dbstop.sh +4 -0
  213. package/docs/.nojekyll +1 -0
  214. package/docs/README.md +130 -0
  215. package/docs/classes/Hot.md +477 -0
  216. package/docs/classes/HotAPI.md +369 -0
  217. package/docs/classes/HotClient.md +95 -0
  218. package/docs/classes/HotComponent.md +279 -0
  219. package/docs/classes/HotDB.md +247 -0
  220. package/docs/classes/HotDBInflux.md +404 -0
  221. package/docs/classes/HotDBMigration.md +80 -0
  222. package/docs/classes/HotDBMySQL.md +310 -0
  223. package/docs/classes/HotDBSchema.md +51 -0
  224. package/docs/classes/HotFile.md +353 -0
  225. package/docs/classes/HotHTTPServer.md +700 -0
  226. package/docs/classes/HotLog.md +162 -0
  227. package/docs/classes/HotPage.md +357 -0
  228. package/docs/classes/HotRoute.md +312 -0
  229. package/docs/classes/HotRouteMethod.md +271 -0
  230. package/docs/classes/HotServer.md +311 -0
  231. package/docs/classes/HotStaq.md +1155 -0
  232. package/docs/classes/HotTestDestination.md +58 -0
  233. package/docs/classes/HotTestDriver.md +332 -0
  234. package/docs/classes/HotTestElement.md +88 -0
  235. package/docs/classes/HotTestElementOptions.md +71 -0
  236. package/docs/classes/HotTestMap.md +92 -0
  237. package/docs/classes/HotTestSeleniumDriver.md +542 -0
  238. package/docs/classes/HotTester.md +653 -0
  239. package/docs/classes/HotTesterAPI.md +493 -0
  240. package/docs/classes/HotTesterMocha.md +843 -0
  241. package/docs/classes/HotTesterMochaSelenium.md +896 -0
  242. package/docs/classes/HotTesterServer.md +633 -0
  243. package/docs/classes/InfluxSchema.md +74 -0
  244. package/docs/classes/MySQLSchema.md +199 -0
  245. package/docs/classes/MySQLSchemaField.md +330 -0
  246. package/docs/classes/MySQLSchemaTable.md +176 -0
  247. package/docs/enums/ConnectionStatus.md +43 -0
  248. package/docs/enums/DeveloperMode.md +38 -0
  249. package/docs/enums/EventExecutionType.md +43 -0
  250. package/docs/enums/HTTPMethod.md +32 -0
  251. package/docs/enums/HotDBGenerationType.md +30 -0
  252. package/docs/enums/HotLogLevel.md +88 -0
  253. package/docs/interfaces/HotDBConnectionInterface.md +116 -0
  254. package/docs/interfaces/HotDestination.md +62 -0
  255. package/docs/interfaces/HotSite.md +187 -0
  256. package/docs/interfaces/HotSiteMapPath.md +37 -0
  257. package/docs/interfaces/HotSiteRoute.md +79 -0
  258. package/docs/interfaces/HotStartOptions.md +115 -0
  259. package/docs/interfaces/HotTestPage.md +44 -0
  260. package/docs/interfaces/HotTestStop.md +62 -0
  261. package/docs/interfaces/IHotComponent.md +135 -0
  262. package/docs/interfaces/IHotStaq.md +118 -0
  263. package/docs/interfaces/IHotTestElement.md +54 -0
  264. package/docs/interfaces/IHotTestElementOptions.md +43 -0
  265. package/docs/interfaces/MySQLResults.md +43 -0
  266. package/docs/interfaces/MySQLSchemaFieldResult.md +75 -0
  267. package/docs/modules.md +182 -0
  268. package/package.json +65 -0
  269. package/selenium-start.sh +7 -0
  270. package/selenium-stop.sh +3 -0
  271. package/src/Hot.ts +319 -0
  272. package/src/HotAPI.ts +386 -0
  273. package/src/HotAgentAPI.ts +43 -0
  274. package/src/HotAgentRoute.ts +44 -0
  275. package/src/HotBuilder.ts +221 -0
  276. package/src/HotClient.ts +40 -0
  277. package/src/HotComponent.ts +158 -0
  278. package/src/HotCreator.ts +470 -0
  279. package/src/HotDB.ts +79 -0
  280. package/src/HotDBConnectionInterface.ts +40 -0
  281. package/src/HotFile.ts +617 -0
  282. package/src/HotGenerator.ts +446 -0
  283. package/src/HotHTTPServer.ts +954 -0
  284. package/src/HotIO.ts +160 -0
  285. package/src/HotLog.ts +158 -0
  286. package/src/HotPage.ts +206 -0
  287. package/src/HotRoute.ts +137 -0
  288. package/src/HotRouteMethod.ts +216 -0
  289. package/src/HotServer.ts +211 -0
  290. package/src/HotSetAsWeb.ts +3 -0
  291. package/src/HotStaq.ts +1881 -0
  292. package/src/HotTestDriver.ts +171 -0
  293. package/src/HotTestElement.ts +97 -0
  294. package/src/HotTestMap.ts +130 -0
  295. package/src/HotTestSeleniumDriver.ts +381 -0
  296. package/src/HotTester.ts +696 -0
  297. package/src/HotTesterAPI.ts +126 -0
  298. package/src/HotTesterMocha.ts +133 -0
  299. package/src/HotTesterMochaSelenium.ts +189 -0
  300. package/src/HotTesterServer.ts +551 -0
  301. package/src/api-web.ts +48 -0
  302. package/src/api.ts +103 -0
  303. package/src/cli.ts +1225 -0
  304. package/src/schemas/HotDBInflux.ts +211 -0
  305. package/src/schemas/HotDBMigration.ts +24 -0
  306. package/src/schemas/HotDBMySQL.ts +312 -0
  307. package/src/schemas/HotDBSchema.ts +21 -0
  308. package/src/schemas/influx/InfluxSchema.ts +19 -0
  309. package/src/schemas/mysql/MySQLSchema.ts +90 -0
  310. package/src/schemas/mysql/MySQLSchemaField.ts +408 -0
  311. package/src/schemas/mysql/MySQLSchemaTable.ts +353 -0
  312. package/temp/HotStaqWeb.ts +59 -0
  313. package/tsconfig-generator.json +17 -0
  314. package/tsconfig-web.json +74 -0
  315. package/tsconfig.json +73 -0
  316. package/webpack.config.generator.js +41 -0
  317. package/webpack.config.js +53 -0
  318. package/webpack.config.tests.js +56 -0
@@ -0,0 +1,954 @@
1
+ import * as http from "http";
2
+ import * as https from "https";
3
+ import * as ppath from "path";
4
+ import * as fs from "fs";
5
+ import { F_OK } from "constants";
6
+
7
+ import express from "express";
8
+ import { Fields, Files, IncomingForm } from "formidable";
9
+
10
+ import { HotServer } from "./HotServer";
11
+ import { HotStaq } from "./HotStaq";
12
+ import { HotRoute } from "./HotRoute";
13
+ import { HotRouteMethod, HTTPMethod } from "./HotRouteMethod";
14
+ import { EventExecutionType, HotAPI } from "./HotAPI";
15
+
16
+ /**
17
+ * A static route.
18
+ */
19
+ export interface StaticRoute
20
+ {
21
+ /**
22
+ * The route to the files.
23
+ */
24
+ route?: string;
25
+ /**
26
+ * The absolute path to the location of the files to
27
+ * serve on this machine.
28
+ */
29
+ localPath?: string;
30
+ }
31
+
32
+ /**
33
+ * A HTTP server.
34
+ */
35
+ export class HotHTTPServer extends HotServer
36
+ {
37
+ /**
38
+ * The express app to use.
39
+ */
40
+ expressApp: express.Express;
41
+ /**
42
+ * The HTTP listener to use.
43
+ */
44
+ httpListener: http.Server;
45
+ /**
46
+ * The HTTPS listener to use.
47
+ */
48
+ httpsListener: https.Server;
49
+ /**
50
+ * The static files and folders to serve.
51
+ */
52
+ staticRoutes: StaticRoute[];
53
+ /**
54
+ * Any non-static routes that need to be added. These
55
+ * will be added during the preregistration phase, before
56
+ * all API routes are added.
57
+ */
58
+ routes: {
59
+ /**
60
+ * The type of route.
61
+ */
62
+ type: HTTPMethod;
63
+ /**
64
+ * The type of route.
65
+ */
66
+ route: string;
67
+ /**
68
+ * The method to execute when this route is hit.
69
+ */
70
+ method: (req: express.Request, res: express.Response) => Promise<void>;
71
+ }[];
72
+ /**
73
+ * Serve hott files when requested. This value will be overwritten by whatever
74
+ * value is set to server.serveHottFiles in HotSite.json.
75
+ */
76
+ serveHottFiles: boolean;
77
+ /**
78
+ * Do not serve these hott files.
79
+ */
80
+ ignoreHottFiles: { [name: string]: boolean };
81
+ /**
82
+ * The associated info with any hott files served. All values here will be
83
+ * overwritten by whatever values are set in the server object in HotSite.json.
84
+ */
85
+ hottFilesAssociatedInfo: {
86
+ /**
87
+ * The default name for a served Hott file.
88
+ */
89
+ name: string;
90
+ /**
91
+ * The base url for a hott file.
92
+ */
93
+ url: string;
94
+ /**
95
+ * The JavaScript source path.
96
+ */
97
+ jsSrcPath: string;
98
+ };
99
+
100
+ constructor (processor: HotStaq | HotServer, httpPort: number = null, httpsPort: number = null)
101
+ {
102
+ super (processor);
103
+
104
+ this.expressApp = express ();
105
+ this.httpListener = null;
106
+ this.httpsListener = null;
107
+ this.staticRoutes = [];
108
+ this.routes = [];
109
+ this.serveHottFiles = true;
110
+ this.ignoreHottFiles = {};
111
+ this.hottFilesAssociatedInfo = {
112
+ name: "",
113
+ url: "./",
114
+ jsSrcPath: "./js/HotStaq.js"
115
+ };
116
+
117
+ if (process.env.LISTEN_ADDR != null)
118
+ {
119
+ if (process.env.LISTEN_ADDR !== "")
120
+ this.listenAddress = process.env.LISTEN_ADDR;
121
+ }
122
+
123
+ if (process.env.USE_HTTP != null)
124
+ {
125
+ this.ssl = {
126
+ cert: "",
127
+ key: "",
128
+ ca: ""
129
+ };
130
+ }
131
+
132
+ if (httpPort != null)
133
+ this.ports.http = httpPort;
134
+
135
+ if (httpsPort != null)
136
+ this.ports.https = httpsPort;
137
+
138
+ if (process.env.HTTP_PORT != null)
139
+ {
140
+ if (process.env.HTTP_PORT !== "")
141
+ this.ports.http = parseInt (process.env.HTTP_PORT);
142
+ }
143
+
144
+ if (process.env.HTTPS_PORT != null)
145
+ {
146
+ if (process.env.HTTPS_PORT !== "")
147
+ this.ports.https = parseInt (process.env.HTTPS_PORT);
148
+ }
149
+
150
+ if (process.env.HTTPS_SSL_CERT != null)
151
+ {
152
+ if (process.env.HTTPS_SSL_CERT !== "")
153
+ this.ssl.cert = process.env.HTTPS_SSL_CERT;
154
+
155
+ if (process.env.HTTPS_SSL_KEY !== "")
156
+ this.ssl.key = process.env.HTTPS_SSL_KEY;
157
+
158
+ if (process.env.HTTPS_SSL_CA !== "")
159
+ this.ssl.ca = process.env.HTTPS_SSL_CA;
160
+ }
161
+
162
+ let JSONLimit: string = "1mb";
163
+
164
+ if (process.env.JSON_LIMIT != null)
165
+ {
166
+ if (process.env.JSON_LIMIT !== "")
167
+ JSONLimit = process.env.JSON_LIMIT;
168
+ }
169
+
170
+ this.expressApp.options ("*", (req: express.Request, res: express.Response, next: express.NextFunction) =>
171
+ {
172
+ res.header ("Access-Control-Allow-Origin", "*");
173
+ res.header ("Access-Control-Allow-Methods", "GET,HEAD,PUT,PATCH,POST,DELETE");
174
+ res.header ("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
175
+
176
+ res.statusCode = 204;
177
+ res.setHeader ("Content-Length", "0");
178
+ res.end ();
179
+ });
180
+ this.expressApp.use ((req: express.Request, res: express.Response, next: express.NextFunction) =>
181
+ {
182
+ res.header ("Access-Control-Allow-Origin", "*");
183
+ res.header ("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
184
+
185
+ next ();
186
+ });
187
+ this.expressApp.use (express.urlencoded ({ "extended": true }));
188
+ this.expressApp.use (express.json ({ "limit": JSONLimit }));
189
+ }
190
+
191
+ /**
192
+ * Add a static route.
193
+ */
194
+ addStaticRoute (route: string | StaticRoute, localPath: string = "."): void
195
+ {
196
+ let staticRoute: StaticRoute = null;
197
+
198
+ if (typeof (route) === "string")
199
+ {
200
+ staticRoute = {
201
+ "route": route,
202
+ "localPath": localPath
203
+ };
204
+ }
205
+ else
206
+ staticRoute = route;
207
+
208
+ this.staticRoutes.push (staticRoute);
209
+ this.registerStaticRoute (staticRoute);
210
+ }
211
+
212
+ /**
213
+ * Add a route. This will be registered before any APIs are registered.
214
+ */
215
+ addRoute (route: string, method: (req: express.Request, res: express.Response) => Promise<void>,
216
+ type: HTTPMethod = HTTPMethod.GET): void
217
+ {
218
+ let newRoute = {
219
+ type: type,
220
+ route: route,
221
+ method: method
222
+ };
223
+
224
+ this.routes.push (newRoute);
225
+ }
226
+
227
+ /**
228
+ * Serve a directory. This is an alias for addStaticRoute.
229
+ */
230
+ serveDirectory (route: string | StaticRoute, localPath: string = "."): void
231
+ {
232
+ this.addStaticRoute (route, localPath);
233
+ }
234
+
235
+ /**
236
+ * Register a static route with Express.
237
+ */
238
+ registerStaticRoute (route: StaticRoute): void
239
+ {
240
+ this.clearErrorHandlingRoutes ();
241
+ this.preregisterRoute ();
242
+
243
+ this.expressApp.use (route.route, express.static (ppath.normalize (route.localPath)));
244
+ this.logger.verbose (`Adding static route ${route.route} at path ${route.localPath}`);
245
+
246
+ this.setErrorHandlingRoutes ();
247
+ }
248
+
249
+ /**
250
+ * Get a static route.
251
+ */
252
+ getStaticRoute (route: string): StaticRoute
253
+ {
254
+ let foundRoute: StaticRoute = null;
255
+
256
+ for (let iIdx = 0; iIdx < this.staticRoutes.length; iIdx++)
257
+ {
258
+ let tempRoute: StaticRoute = this.staticRoutes[iIdx];
259
+
260
+ if (tempRoute.route === route)
261
+ {
262
+ foundRoute = tempRoute;
263
+
264
+ break;
265
+ }
266
+ }
267
+
268
+ return (foundRoute);
269
+ }
270
+
271
+ /**
272
+ * Register a route.
273
+ */
274
+ async registerRoute (route: HotRoute): Promise<void>
275
+ {
276
+ try
277
+ {
278
+ if (route.onRegister != null)
279
+ {
280
+ if (await route.onRegister () === false)
281
+ return;
282
+ }
283
+
284
+ this.clearErrorHandlingRoutes ();
285
+ this.preregisterRoute ();
286
+
287
+ for (let iIdx = 0; iIdx < route.methods.length; iIdx++)
288
+ {
289
+ let method: HotRouteMethod = route.methods[iIdx];
290
+
291
+ if (method.isRegistered === true)
292
+ continue;
293
+
294
+ if (method.onRegister != null)
295
+ {
296
+ if (await method.onRegister () === false)
297
+ continue;
298
+ }
299
+
300
+ let methodName: string = "/";
301
+
302
+ if (route.version !== "")
303
+ methodName += `${route.version}/`;
304
+
305
+ if (route.prefix !== "")
306
+ methodName += `${route.prefix}/`;
307
+
308
+ if (route.route !== "")
309
+ methodName += `${route.route}/`;
310
+
311
+ methodName += method.name;
312
+ method.isRegistered = true;
313
+
314
+ this.logger.verbose (`Adding route ${method.type} ${methodName}`);
315
+ this.expressApp[method.type] (methodName,
316
+ async (req: express.Request, res: express.Response) =>
317
+ {
318
+ let hasAuthorization: boolean = true;
319
+ let authorizationValue: any = null;
320
+ let jsonObj: any = req.body;
321
+ let queryObj: any = req.query;
322
+ let api: HotAPI = route.connection.api;
323
+ let thisObj: any = route;
324
+
325
+ if (api.executeEventsUsing === EventExecutionType.HotAPI)
326
+ thisObj = api;
327
+
328
+ if (api.executeEventsUsing === EventExecutionType.HotMethod)
329
+ thisObj = method;
330
+
331
+ this.logger.verbose (`${req.method} ${methodName}, JSON: ${JSON.stringify (jsonObj)}, Query: ${JSON.stringify (queryObj)}`);
332
+
333
+ if (method.onServerAuthorize != null)
334
+ {
335
+ try
336
+ {
337
+ authorizationValue =
338
+ await method.onServerAuthorize.call (thisObj, req, res, jsonObj, queryObj);
339
+ }
340
+ catch (ex)
341
+ {
342
+ this.logger.verbose (`Authorization error: ${ex.message}`);
343
+ res.json ({ error: ex.message });
344
+ hasAuthorization = false;
345
+
346
+ return;
347
+ }
348
+
349
+ if (authorizationValue === undefined)
350
+ hasAuthorization = false;
351
+ }
352
+ else
353
+ {
354
+ if (route.onAuthorizeUser != null)
355
+ {
356
+ try
357
+ {
358
+ authorizationValue = await route.onAuthorizeUser (req, res);
359
+ }
360
+ catch (ex)
361
+ {
362
+ this.logger.verbose (`Authorization error: ${ex.message}`);
363
+ res.json ({ error: ex.message });
364
+ hasAuthorization = false;
365
+
366
+ return;
367
+ }
368
+
369
+ if (authorizationValue === undefined)
370
+ hasAuthorization = false;
371
+ }
372
+ }
373
+
374
+ this.logger.verbose (`${req.method} ${methodName}, Authorized: ${hasAuthorization}, Authorization Value: ${authorizationValue}`);
375
+
376
+ if (hasAuthorization === true)
377
+ {
378
+ if (method.onServerExecute != null)
379
+ {
380
+ try
381
+ {
382
+ let result: any =
383
+ await method.onServerExecute.call (
384
+ thisObj, req, res, authorizationValue, jsonObj, queryObj);
385
+
386
+ this.logger.verbose (`${req.method} ${methodName}, Response: ${result}`);
387
+
388
+ if (result !== undefined)
389
+ res.json (result);
390
+ }
391
+ catch (ex)
392
+ {
393
+ this.logger.verbose (`Execution error: ${ex.message}`);
394
+ res.json ({ error: ex.message });
395
+ }
396
+ }
397
+ }
398
+ else
399
+ {
400
+ res.json (route.errors["not_authorized"]);
401
+ this.logger.verbose (`${req.method} ${methodName}, not_authorized`);
402
+ }
403
+ });
404
+ }
405
+
406
+ this.setErrorHandlingRoutes ();
407
+ }
408
+ catch (ex)
409
+ {
410
+ let msg: string = ex.message;
411
+
412
+ if (ex.stack != null)
413
+ msg = ex.stack;
414
+
415
+ this.logger.error (`HotHTTPServer error: ${msg}`);
416
+ throw ex;
417
+ }
418
+ }
419
+
420
+ /**
421
+ * Check if a file exists.
422
+ */
423
+ static async checkIfFileExists (filepath: string): Promise<boolean>
424
+ {
425
+ return (await new Promise<boolean> ((resolve, reject) =>
426
+ {
427
+ fs.access (filepath, F_OK, (err: NodeJS.ErrnoException) =>
428
+ {
429
+ if (err != null)
430
+ resolve (false);
431
+
432
+ resolve (true);
433
+ });
434
+ }));
435
+ }
436
+
437
+ /**
438
+ * The routes to add before registering a route.
439
+ */
440
+ preregisterRoute (): void
441
+ {
442
+ this.expressApp.use ((req: express.Request, res: express.Response, next: any): void =>
443
+ {
444
+ const url: string = `${req.protocol}://${req.get ("host")}${req.originalUrl}`;
445
+ this.logger.verbose (`Requested: ${req.method} ${req.httpVersion} ${url}`);
446
+
447
+ next ();
448
+ });
449
+
450
+ for (let iIdx = 0; iIdx < this.routes.length; iIdx++)
451
+ {
452
+ let route = this.routes[iIdx];
453
+
454
+ this.expressApp[route.type] (route.route, route.method);
455
+ this.logger.verbose (`Adding route ${route.type} ${route.route}`);
456
+ }
457
+
458
+ let serveHottFiles: boolean = this.serveHottFiles;
459
+
460
+ if (this.processor.hotSite != null)
461
+ {
462
+ if (this.processor.hotSite.server != null)
463
+ {
464
+ if (this.processor.hotSite.server.serveHottFiles != null)
465
+ serveHottFiles = this.processor.hotSite.server.serveHottFiles;
466
+ }
467
+
468
+ if (this.processor.hotSite.routes != null)
469
+ {
470
+ // Ignore any hott files from any routes. The routes will return the
471
+ // hott files themselves.
472
+ for (let key in this.processor.hotSite.routes)
473
+ {
474
+ let route = this.processor.hotSite.routes[key];
475
+ let filename: string = ppath.basename (route.url);
476
+
477
+ this.ignoreHottFiles[filename] = true;
478
+ this.logger.verbose (`Ignoring Hott file ${filename}`);
479
+ }
480
+ }
481
+ }
482
+
483
+ if (serveHottFiles === true)
484
+ {
485
+ this.logger.verbose (`Set to serve hott files...`);
486
+
487
+ this.expressApp.use ((req: express.Request, res: express.Response, next: any): void =>
488
+ {
489
+ (async () =>
490
+ {
491
+ let bodyObj: any = req.body;
492
+ let queryObj: any = req.query;
493
+
494
+ this.logger.verbose (`Method: ${req.method} Requested URL: ${req.originalUrl} Body: ${JSON.stringify (bodyObj)}, Query: ${JSON.stringify (queryObj)}`);
495
+
496
+ let requestedUrl: string = `${req.protocol}://${req.get("host")}${req.originalUrl}`;
497
+ let foundUrl: string = HotStaq.getValueFromHotSiteObj (this.processor.hotSite, ["server", "url"]);
498
+
499
+ if (foundUrl != null)
500
+ {
501
+ if (foundUrl[(foundUrl.length - 1)] === "/")
502
+ foundUrl = foundUrl.substr (0, (foundUrl.length - 1));
503
+
504
+ requestedUrl = `${foundUrl}/${req.originalUrl}`;
505
+ }
506
+
507
+ let url: URL = new URL (requestedUrl);
508
+ const urlFilepath: string = url.pathname;
509
+ const filepath: string = ppath.basename (urlFilepath);
510
+
511
+ // This if statement ensures the requested file is not on the ignore list.
512
+ if (this.ignoreHottFiles[filepath] == null)
513
+ {
514
+ let sendHottContent = (fullUrl: URL, route: string): void =>
515
+ {
516
+ // Appending hpserve ensures that the content will not be resent.
517
+ fullUrl.searchParams.append ("hpserve", "nahfam");
518
+
519
+ const content: string = this.processor.generateContent (route,
520
+ this.hottFilesAssociatedInfo.name,
521
+ fullUrl.toString (),
522
+ this.hottFilesAssociatedInfo.jsSrcPath);
523
+ // The content will be generated and sent to the client. The client
524
+ // will then request the real page that contains the file.
525
+
526
+ res.setHeader ("Content-Type", "text/html");
527
+ res.send (content);
528
+ };
529
+
530
+ let result: string = "";
531
+ let hpserve = url.searchParams.get ("hpserve");
532
+
533
+ if (hpserve != null)
534
+ result = hpserve;
535
+
536
+ // Make sure we're not accidentally resending the content.
537
+ if (result !== "nahfam")
538
+ {
539
+ let serveDirectories: {
540
+ route: string;
541
+ localPath: string;
542
+ }[] = HotStaq.getValueFromHotSiteObj (
543
+ this.processor.hotSite, ["server", "serveDirectories"]);
544
+ let checkDirs: string[] = [];
545
+
546
+ if (serveDirectories != null)
547
+ {
548
+ if (serveDirectories.length > 0)
549
+ {
550
+ for (let iIdx = 0; iIdx < serveDirectories.length; iIdx++)
551
+ {
552
+ const serveDir: string = serveDirectories[iIdx].localPath;
553
+
554
+ checkDirs.push (serveDir);
555
+ }
556
+ }
557
+ }
558
+
559
+ if (checkDirs.length < 1)
560
+ checkDirs.push (process.cwd ());
561
+
562
+ for (let iIdx = 0; iIdx < checkDirs.length; iIdx++)
563
+ {
564
+ let checkDir: string = checkDirs[iIdx];
565
+ const route: string = urlFilepath;
566
+ let tempFilepath: string = urlFilepath;
567
+ let sendContentFlag: boolean = false;
568
+
569
+ if (tempFilepath.indexOf (".hott") > -1)
570
+ {
571
+ if (await HotHTTPServer.checkIfFileExists (
572
+ ppath.normalize (`${checkDir}/${tempFilepath}`)) === true)
573
+ {
574
+ sendContentFlag = true;
575
+ }
576
+ }
577
+
578
+ if (sendContentFlag === false)
579
+ {
580
+ if (await HotHTTPServer.checkIfFileExists (
581
+ ppath.normalize (`${checkDir}/${tempFilepath}.hott`)) === true)
582
+ {
583
+ sendContentFlag = true;
584
+ url.pathname += ".hott";
585
+ }
586
+ }
587
+
588
+ if (sendContentFlag === false)
589
+ {
590
+ // If no content has been found, send the index.
591
+ tempFilepath += "index.hott";
592
+
593
+ if (await HotHTTPServer.checkIfFileExists (
594
+ ppath.normalize (`${checkDir}/${tempFilepath}`)) === true)
595
+ {
596
+ sendContentFlag = true;
597
+ }
598
+ }
599
+
600
+ if (tempFilepath !== urlFilepath)
601
+ url.pathname = tempFilepath;
602
+
603
+ if (sendContentFlag === true)
604
+ {
605
+ sendHottContent (url, route);
606
+
607
+ return;
608
+ }
609
+ }
610
+ }
611
+ }
612
+
613
+ next ();
614
+ })();
615
+ });
616
+ }
617
+ }
618
+
619
+ /**
620
+ * Get all files uploaded.
621
+ */
622
+ static async getFileUploads (req: express.Request, options: any = { multiples: true }): Promise<Files>
623
+ {
624
+ return (await new Promise<Files> ((resolve, reject) =>
625
+ {
626
+ const form = new IncomingForm (options);
627
+
628
+ form.parse (req, (err: any, fields: Fields, files: Files) =>
629
+ {
630
+ if (err != null)
631
+ throw err;
632
+
633
+ resolve (files);
634
+ });
635
+ }));
636
+ }
637
+
638
+ /**
639
+ * Set the error handlers. This will create two express routes at the bottom of the
640
+ * route stack. The first will be to capture any 404 errors, the second would be to
641
+ * catch any remaining errors.
642
+ */
643
+ setErrorHandlingRoutes (
644
+ handle404: (req: express.Request, res: express.Response, next: any) => void = null,
645
+ handleOther: (err: any, req: express.Request, res: express.Response, next: any) => void = null
646
+ ): void
647
+ {
648
+ if (handle404 == null)
649
+ {
650
+ handle404 = (req: express.Request, res: express.Response, next: any): void =>
651
+ {
652
+ this.logger.verbose (`404 ${JSON.stringify (req.url)}`);
653
+ res.status (404).send ({ error: "404" });
654
+ };
655
+ }
656
+
657
+ if (handleOther == null)
658
+ {
659
+ handleOther = (err: any, req: express.Request, res: express.Response, next: any): void =>
660
+ {
661
+ let stack: string = "";
662
+ let msg: string = "";
663
+
664
+ if (err != null)
665
+ {
666
+ stack = err.stack;
667
+ msg = err.message;
668
+ }
669
+
670
+ this.logger.verbose (`500 Server error ${JSON.stringify (stack)}`);
671
+ res.status (500).send ({ error: `Server error: ${msg}` });
672
+ };
673
+ }
674
+
675
+ this.expressApp.use (handle404);
676
+ this.expressApp.use (handleOther);
677
+ }
678
+
679
+ /**
680
+ * Clear the last two express routes, which are reserved for the
681
+ * error handlers.
682
+ */
683
+ clearErrorHandlingRoutes (): void
684
+ {
685
+ if (this.expressApp._router == null)
686
+ return;
687
+
688
+ let stackCount: number = this.expressApp._router.stack.length;
689
+
690
+ for (let iIdx = 0; iIdx < stackCount; iIdx++)
691
+ {
692
+ let elm: any = this.expressApp._router.stack[iIdx];
693
+
694
+ if (elm != null)
695
+ {
696
+ let name: string = elm.name;
697
+
698
+ if ((name === "handle404") || (name === "handleOther"))
699
+ {
700
+ (<any[]>this.expressApp._router.stack).splice (iIdx, 1);
701
+ iIdx--;
702
+ stackCount = this.expressApp._router.stack.length;
703
+ }
704
+ }
705
+ }
706
+ }
707
+
708
+ /**
709
+ * Start listening for requests.
710
+ */
711
+ async listen (): Promise<void>
712
+ {
713
+ let promise: Promise<void> = new Promise<void> (
714
+ async (resolve, reject) =>
715
+ {
716
+ try
717
+ {
718
+ let completedSetup = () =>
719
+ {
720
+ let protocol: string = "http";
721
+ let port: number = this.ports.http;
722
+
723
+ if (this.ssl.cert !== "")
724
+ {
725
+ protocol = "https";
726
+ port = this.ports.https;
727
+ }
728
+
729
+ this.logger.info (`${this.serverType} running at ${protocol}://${this.listenAddress}:${port}/`);
730
+ resolve ();
731
+ };
732
+
733
+ if (this.processor.hotSite != null)
734
+ {
735
+ let hotsiteServer = this.processor.hotSite.server;
736
+
737
+ if (hotsiteServer != null)
738
+ {
739
+ if (hotsiteServer.serveDirectories != null)
740
+ {
741
+ for (let iIdx = 0; iIdx < hotsiteServer.serveDirectories.length; iIdx++)
742
+ {
743
+ let directory = hotsiteServer.serveDirectories[iIdx];
744
+
745
+ this.staticRoutes.push ({
746
+ "route": directory.route,
747
+ "localPath": ppath.normalize (directory.localPath)
748
+ });
749
+ }
750
+ }
751
+
752
+ if (hotsiteServer.ports != null)
753
+ {
754
+ if (hotsiteServer.ports.http != null)
755
+ this.ports.http = hotsiteServer.ports.http;
756
+
757
+ if (hotsiteServer.ports.https != null)
758
+ this.ports.https = hotsiteServer.ports.https;
759
+
760
+ if (hotsiteServer.ports.redirectHTTPtoHTTPS != null)
761
+ this.redirectHTTPtoHTTPS = hotsiteServer.ports.redirectHTTPtoHTTPS;
762
+ }
763
+ }
764
+ }
765
+
766
+ this.processor.createExpressRoutes (this.expressApp);
767
+
768
+ for (let iIdx = 0; iIdx < this.staticRoutes.length; iIdx++)
769
+ {
770
+ let staticRoute: StaticRoute = this.staticRoutes[iIdx];
771
+
772
+ this.registerStaticRoute (staticRoute);
773
+ }
774
+
775
+ if (this.api != null)
776
+ {
777
+ if (this.api.onPreRegister != null)
778
+ {
779
+ let continueRegistering: boolean = await this.api.onPreRegister ();
780
+
781
+ if (continueRegistering === false)
782
+ return;
783
+ }
784
+
785
+ // Process pre registration for the routes and methods.
786
+ for (let key in this.api.routes)
787
+ {
788
+ let route: HotRoute = this.api.routes[key];
789
+
790
+ if (route.onPreRegister != null)
791
+ await route.onPreRegister ();
792
+
793
+ for (let iIdx = 0; iIdx < route.methods.length; iIdx++)
794
+ {
795
+ let method: HotRouteMethod = route.methods[iIdx];
796
+
797
+ if (method.onPreRegister != null)
798
+ await method.onPreRegister ();
799
+ }
800
+ }
801
+
802
+ // Register all the routes.
803
+ await this.api.registerRoutes ();
804
+
805
+ // Process post registration for the API.
806
+ if (this.api.onPostRegister != null)
807
+ {
808
+ let continueOn: boolean = await this.api.onPostRegister ();
809
+
810
+ if (continueOn === false)
811
+ return;
812
+ }
813
+
814
+ // Process post registration for the routes and methods.
815
+ for (let key in this.api.routes)
816
+ {
817
+ let route: HotRoute = this.api.routes[key];
818
+
819
+ if (route.onPostRegister != null)
820
+ await route.onPostRegister ();
821
+
822
+ for (let iIdx = 0; iIdx < route.methods.length; iIdx++)
823
+ {
824
+ let method: HotRouteMethod = route.methods[iIdx];
825
+
826
+ if (method.onPostRegister != null)
827
+ await method.onPostRegister ();
828
+ }
829
+ }
830
+ }
831
+
832
+ if (this.ssl.cert === "")
833
+ {
834
+ this.httpListener = http.createServer (this.expressApp);
835
+ this.httpListener.listen (this.ports.http, this.listenAddress, completedSetup);
836
+ }
837
+ else
838
+ {
839
+ if (this.redirectHTTPtoHTTPS === true)
840
+ {
841
+ this.httpListener = http.createServer ((req: http.IncomingMessage, res: http.ServerResponse) =>
842
+ {
843
+ let host: string = req.headers["host"];
844
+
845
+ res.writeHead (301, {
846
+ "Location": `https://${host}${req.url}`
847
+ });
848
+ res.end ();
849
+ });
850
+ this.httpListener.listen (this.ports.http, this.listenAddress, () =>
851
+ {
852
+ this.logger.info (`Redirecting HTTP(${this.ports.http}) traffic to HTTPS(${this.ports.https})`);
853
+ });
854
+ }
855
+
856
+ this.httpsListener = https.createServer ({
857
+ cert: this.ssl.cert,
858
+ key: this.ssl.key,
859
+ ca: this.ssl.ca
860
+ }, this.expressApp);
861
+ this.httpsListener.listen (this.ports.https, this.listenAddress, completedSetup);
862
+ }
863
+ }
864
+ catch (ex)
865
+ {
866
+ let msg: string = ex.message;
867
+
868
+ if (ex.stack != null)
869
+ msg = ex.stack;
870
+
871
+ this.logger.error (`HotHTTPServer Error: ${msg}`);
872
+ throw (ex);
873
+ }
874
+ })
875
+ .catch ((reason: any) =>
876
+ {
877
+ let msg: string = "";
878
+
879
+ if (typeof (reason) === "string")
880
+ msg = reason;
881
+
882
+ if (reason.message != null)
883
+ msg = reason.message;
884
+
885
+ if (reason.stack != null)
886
+ msg = reason.stack;
887
+
888
+ this.logger.error (`HotHTTPServer Error: ${msg}`);
889
+ throw reason;
890
+ });
891
+
892
+ return (promise);
893
+ }
894
+
895
+ /**
896
+ * Start the server.
897
+ *
898
+ * @param localStaticPath The public path that contains the HTML, Hott files, images, and
899
+ * all public content. This can also be an array of StaticRoutes.
900
+ * @param httpPort The HTTP port to listen on .
901
+ * @param httpsPort The HTTPS port to listen on.
902
+ * @param processor The HotStaq or parent server being used for communication.
903
+ */
904
+ static async startServer (localStaticPath: string | StaticRoute[] = null,
905
+ httpPort: number = 80, httpsPort: number = 443,
906
+ processor: HotServer | HotStaq = null,):
907
+ Promise<{ processor: HotServer | HotStaq; server: HotHTTPServer; }>
908
+ {
909
+ if (processor == null)
910
+ processor = new HotStaq ();
911
+
912
+ let webServer: HotHTTPServer = new HotHTTPServer (processor, httpPort, httpsPort);
913
+
914
+ if (localStaticPath == null)
915
+ localStaticPath = process.cwd ();
916
+
917
+ if (typeof (localStaticPath) === "string")
918
+ webServer.addStaticRoute ("/", localStaticPath);
919
+ else
920
+ {
921
+ for (let iIdx = 0; iIdx < localStaticPath.length; iIdx++)
922
+ {
923
+ let staticRoute: StaticRoute = localStaticPath[iIdx];
924
+
925
+ webServer.addStaticRoute (staticRoute);
926
+ }
927
+ }
928
+
929
+ await webServer.listen ();
930
+
931
+ return ({ processor: processor, server: webServer });
932
+ }
933
+
934
+ /**
935
+ * Shutdown the server.
936
+ */
937
+ async shutdown (): Promise<void>
938
+ {
939
+ this.logger.verbose (`Shutting down HTTP server...`);
940
+ await new Promise<void> ((resolve, reject) =>
941
+ {
942
+ this.httpListener.close ((err: Error) =>
943
+ {
944
+ this.expressApp = null;
945
+
946
+ if (err != null)
947
+ throw err;
948
+
949
+ this.logger.verbose (`HTTP server has shut down.`);
950
+ resolve ();
951
+ });
952
+ });
953
+ }
954
+ }