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
package/src/cli.ts ADDED
@@ -0,0 +1,1225 @@
1
+ import * as ppath from "path";
2
+ import * as fs from "fs";
3
+
4
+ import * as commander from "commander";
5
+
6
+ import { HotStaq } from "./HotStaq";
7
+ import { HotHTTPServer } from "./HotHTTPServer";
8
+ import { HotLogLevel } from "./HotLog";
9
+ import { DeveloperMode } from "./Hot";
10
+ import { HotTesterServer } from "./HotTesterServer";
11
+ import { HotBuilder } from "./HotBuilder";
12
+ import { HotGenerator } from "./HotGenerator";
13
+ import { HotCreator } from "./HotCreator";
14
+ import { HotDBConnectionInterface } from "./HotDBConnectionInterface";
15
+ import { APItoLoad, HotAPI } from "./HotAPI";
16
+ import { HotTesterMochaSelenium } from "./HotTesterMochaSelenium";
17
+ import { HotDBMySQL } from "./schemas/HotDBMySQL";
18
+ import { HotIO } from "./HotIO";
19
+ import { HotAgentAPI } from "./HotAgentAPI";
20
+ import { HotTester } from "./HotTester";
21
+ import { HotTesterMocha } from "./HotTesterMocha";
22
+
23
+ HotStaq.isWeb = false;
24
+
25
+ let VERSION: string = "";
26
+ let processor: HotStaq = new HotStaq ();
27
+ processor.logger.logLevel = HotLogLevel.All;
28
+
29
+ let hotsitePath: string = "";
30
+ let globalLogLevel: HotLogLevel = null;
31
+
32
+ /**
33
+ * Start the API server.
34
+ */
35
+ async function startAPIServer (server: HotHTTPServer, loadedAPI: APItoLoad, baseAPIUrl:
36
+ string, dbinfo: HotDBConnectionInterface, isAPIOnly: boolean): Promise<HotAPI>
37
+ {
38
+ process.chdir (process.cwd ());
39
+ let foundModulePath = require.resolve (loadedAPI.path, { paths: [process.cwd ()] });
40
+ let apiJS = require (foundModulePath);
41
+ let apiClass: any = apiJS[loadedAPI.exportedClassName];
42
+ let api: HotAPI = new apiClass (baseAPIUrl, server);
43
+
44
+ server.logger.info (`Loaded API class: ${loadedAPI.exportedClassName}`);
45
+
46
+ server.processor.api = api;
47
+ server.api = api;
48
+
49
+ if (isAPIOnly === true)
50
+ {
51
+ server.addRoute ("/", async (req: any, res: any) =>
52
+ {
53
+ res.json ({ "status": "ok" });
54
+ });
55
+ }
56
+
57
+ if (dbinfo != null)
58
+ {
59
+ let dbClass = null;
60
+
61
+ if (dbinfo.type === "mysql")
62
+ dbClass = HotDBMySQL;
63
+
64
+ api.db = new dbClass ();
65
+ await server.setAPI (api);
66
+
67
+ if (dbinfo.username === "")
68
+ throw new Error (`No database username provided!`);
69
+
70
+ if (dbinfo.password === "")
71
+ throw new Error (`No database password provided!`);
72
+
73
+ await api.db.connect (dbinfo);
74
+ }
75
+
76
+ return (api);
77
+ }
78
+
79
+ /**
80
+ * Get a key/value pair from a string.
81
+ */
82
+ function getKeyValuePair (str: string): { key: string; value: string; }
83
+ {
84
+ let pos: number = str.indexOf ("=");
85
+ let key: string = "";
86
+ let value: string = "";
87
+
88
+ if (pos > -1)
89
+ {
90
+ key = str.substr (0, pos);
91
+ value = str.substr (pos + 1);
92
+ }
93
+
94
+ return ({ key: key, value: value });
95
+ }
96
+
97
+ /**
98
+ * Handle any build commands.
99
+ */
100
+ async function handleBuildCommands (): Promise<commander.Command>
101
+ {
102
+ let builder: HotBuilder = null;
103
+ let createHotBuilder = () =>
104
+ {
105
+ if (builder == null)
106
+ builder = new HotBuilder (processor.logger);
107
+ };
108
+
109
+ const buildCmd: commander.Command = new commander.Command ("build");
110
+ buildCmd.description (`Build commands.`);
111
+ buildCmd.action (async () =>
112
+ {
113
+ createHotBuilder ();
114
+
115
+ if (hotsitePath === "")
116
+ {
117
+ let tempHotsitePath: string = ppath.normalize (`${process.cwd ()}/HotSite.json`);
118
+
119
+ /// @fixme Do this check without caps sensitivity.
120
+ if (await HotIO.exists (tempHotsitePath) === true)
121
+ hotsitePath = tempHotsitePath;
122
+ }
123
+
124
+ if (hotsitePath === "")
125
+ throw new Error (`When building, you must specify a HotSite.json!`);
126
+
127
+ if (hotsitePath !== "")
128
+ await processor.loadHotSite (hotsitePath);
129
+
130
+ builder.hotsites = [processor.hotSite];
131
+ await builder.build ();
132
+ });
133
+
134
+ /*buildCmd.option ("--watch, -w", "Watch the associated files and rebuild when changes are detected.",
135
+ (arg: string, previous: any) =>
136
+ {
137
+ createHotBuilder ();
138
+ builder.api = true;
139
+ });*/
140
+ /*buildCmd.option ("--api", "Build the web client to be used in a web browser.",
141
+ (arg: string, previous: any) =>
142
+ {
143
+ createHotBuilder ();
144
+ builder.api = true;
145
+ });*/
146
+ buildCmd.option ("--docker", "Build Dockerfiles from the given HotSite.json. This will be the default option.",
147
+ (arg: string, previous: any) =>
148
+ {
149
+ createHotBuilder ();
150
+ builder.dockerFiles = true;
151
+ });
152
+ buildCmd.option ("--dont-get-hard", "Do not use the default security hardening when generating the docker image.",
153
+ (arg: string, previous: any) =>
154
+ {
155
+ createHotBuilder ();
156
+ builder.dockerHardenSecurity = true;
157
+ });
158
+ buildCmd.option ("--dont-append-readme", "Do not add the additional docker documentation to the existing README.md.",
159
+ (arg: string, previous: any) =>
160
+ {
161
+ createHotBuilder ();
162
+ builder.appendReadMe = true;
163
+ });
164
+ /*buildCmd.option ("--docker-compose", "Build the docker compose file from the given HotSite.json.",
165
+ (arg: string, previous: any) =>
166
+ {
167
+ createHotBuilder ();
168
+ builder.dockerCompose = true;
169
+ });
170
+ buildCmd.option ("--kubernetes", "Build a Kubernetes cluster from the given HotSite.json.",
171
+ (arg: string, previous: any) =>
172
+ {
173
+ createHotBuilder ();
174
+ builder.kubernetes = true;
175
+ });*/
176
+ buildCmd.option ("--output", "The directory path to place all files.",
177
+ (arg: string, previous: any) =>
178
+ {
179
+ createHotBuilder ();
180
+ builder.outputDir = arg;
181
+ });
182
+
183
+ return (buildCmd);
184
+ }
185
+
186
+ /**
187
+ * Handle create commands.
188
+ */
189
+ async function handleCreateCommands (): Promise<commander.Command>
190
+ {
191
+ let creator: HotCreator = null;
192
+ let createHotCreator = () =>
193
+ {
194
+ if (creator == null)
195
+ creator = new HotCreator (processor.logger);
196
+ };
197
+
198
+ let copyLibrariesPath: string = "";
199
+ const createCmd: commander.Command = new commander.Command ("create");
200
+ createCmd.description (`Create a new project.`);
201
+ createCmd.action (async (cmdr: any, args: string) =>
202
+ {
203
+ createHotCreator ();
204
+
205
+ if (copyLibrariesPath !== "")
206
+ {
207
+ await creator.copyLibraries (copyLibrariesPath);
208
+
209
+ return;
210
+ }
211
+
212
+ if (args == null)
213
+ throw new Error (`You must supply an npm compatible project name!`);
214
+
215
+ if (args.length < 1)
216
+ throw new Error (`You must supply an npm compatible project name!`);
217
+
218
+ const name: string = args[0];
219
+
220
+ creator.name = name;
221
+ creator.outputDir = ppath.normalize (`${process.cwd ()}/${name}/`);
222
+
223
+ await creator.create ();
224
+ });
225
+
226
+ createCmd.option (`--copy-libraries-to-location <path>`,
227
+ `Copy the latest HotStaq libraries to a specified location. This will not generate any projects.`,
228
+ (path: string, previous: any) =>
229
+ {
230
+ createHotCreator ();
231
+ copyLibrariesPath = path;
232
+ }, "");
233
+ createCmd.option (`--type <type>`,
234
+ `The type of app to create. Can be (web, web-api, api)`,
235
+ (type: string, previous: any) =>
236
+ {
237
+ createHotCreator ();
238
+ creator.type = type;
239
+ }, "web-api");
240
+ createCmd.option (`--code <language>`,
241
+ `Set the type of code output. Can be (ts, js) Default: ts`,
242
+ (language: string, previous: any) =>
243
+ {
244
+ createHotCreator ();
245
+ creator.language = language;
246
+ }, "ts");
247
+ createCmd.option (`--output <path>`,
248
+ `The directory path to place all the files.`,
249
+ (path: string, previous: any) =>
250
+ {
251
+ createHotCreator ();
252
+ creator.outputDir = path;
253
+ }, "");
254
+ createCmd.option (`--overwrite-cmd-create-init <value>`,
255
+ `Overwrite the create command for initalizing an app.`,
256
+ (value: string, previous: any) =>
257
+ {
258
+ createHotCreator ();
259
+ creator.createCommands.init = value;
260
+ }, "");
261
+ createCmd.option (`--overwrite-cmd-create-transpile <value>`,
262
+ `Overwrite the create command for transpiling.`,
263
+ (value: string, previous: any) =>
264
+ {
265
+ createHotCreator ();
266
+ creator.createCommands.transpileTS = value;
267
+ }, "");
268
+ createCmd.option (`--overwrite-cmd-npm-build-web-api <value>`,
269
+ `Overwrite the npm command for building the web api.`,
270
+ (value: string, previous: any) =>
271
+ {
272
+ createHotCreator ();
273
+ creator.npmCommands.buildWebAPI = value;
274
+ }, "");
275
+ createCmd.option (`--overwrite-cmd-npm-build-web-api-debug <value>`,
276
+ `Overwrite the npm command for building the debug script for web api.`,
277
+ (value: string, previous: any) =>
278
+ {
279
+ createHotCreator ();
280
+ creator.npmCommands.buildWebAPIDebug = value;
281
+ }, "");
282
+ createCmd.option (`--overwrite-cmd-npm-dev <value>`,
283
+ `Overwrite the npm command for building the development script.`,
284
+ (value: string, previous: any) =>
285
+ {
286
+ createHotCreator ();
287
+ creator.npmCommands.dev = value;
288
+ }, "");
289
+ createCmd.option (`--overwrite-cmd-npm-start <value>`,
290
+ `Overwrite the npm command for the start script.`,
291
+ (value: string, previous: any) =>
292
+ {
293
+ createHotCreator ();
294
+ creator.npmCommands.start = value;
295
+ }, "");
296
+ createCmd.option (`--overwrite-cmd-npm-test <value>`,
297
+ `Overwrite the npm command for the test script.`,
298
+ (value: string, previous: any) =>
299
+ {
300
+ createHotCreator ();
301
+ creator.npmCommands.test = value;
302
+ }, "");
303
+
304
+ return (createCmd);
305
+ }
306
+
307
+ /**
308
+ * Load the APIs from the processor.
309
+ */
310
+ function loadAPIs (processor: HotStaq): { [name: string]: APItoLoad; }
311
+ {
312
+ let apis: { [name: string]: APItoLoad; } = {};
313
+
314
+ if (processor.hotSite != null)
315
+ {
316
+ if (processor.hotSite.apis != null)
317
+ {
318
+ for (let key in processor.hotSite.apis)
319
+ {
320
+ let tempapi = processor.hotSite.apis[key];
321
+
322
+ if (tempapi.libraryName != null)
323
+ {
324
+ let path: string = tempapi.filepath;
325
+
326
+ let apiToLoad: APItoLoad = {
327
+ exportedClassName: tempapi.apiName,
328
+ path: path
329
+ };
330
+ apis[key] = apiToLoad;
331
+ }
332
+ }
333
+ }
334
+ }
335
+
336
+ return (apis);
337
+ }
338
+
339
+ /**
340
+ * Handle run commands.
341
+ */
342
+ async function handleRunCommands (): Promise<commander.Command>
343
+ {
344
+ let webServer: HotHTTPServer = new HotHTTPServer (processor);
345
+ let apiServer: HotHTTPServer = new HotHTTPServer (processor);
346
+ let testerSettings: {
347
+ tester: string;
348
+ address: string;
349
+ browser: string;
350
+ openDevTools: boolean;
351
+ headless: boolean;
352
+ remoteServer: string;
353
+ http: number;
354
+ https: number;
355
+ } = {
356
+ tester: "HotTesterMochaSelenium",
357
+ address: "127.0.0.1",
358
+ browser: "chrome",
359
+ openDevTools: false,
360
+ headless: false,
361
+ remoteServer: "",
362
+ http: 8183,
363
+ https: 4143
364
+ };
365
+ let apis: { [name: string]: APItoLoad; } = {};
366
+ let dbinfo: HotDBConnectionInterface = null;
367
+ let setupDB = () =>
368
+ {
369
+ if (dbinfo != null)
370
+ return;
371
+
372
+ dbinfo = {
373
+ "type": process.env["DATABASE_TYPE"] || "mysql",
374
+ "server": process.env["DATABASE_SERVER"] || "127.0.0.1",
375
+ "username": process.env["DATABASE_USERNAME"] || "",
376
+ "password": process.env["DATABASE_PASSWORD"] || "",
377
+ "org": process.env["DATABASE_ORG"] || "",
378
+ "token": process.env["DATABASE_TOKEN"] || "",
379
+ "port": 3306,
380
+ "database": process.env["DATABASE_SCHEMA"] || ""
381
+ };
382
+
383
+ if (process.env["DATABASE_PORT"] != null)
384
+ {
385
+ try
386
+ {
387
+ dbinfo.port = parseInt (process.env["DATABASE_PORT"]);
388
+ }
389
+ catch (ex)
390
+ {
391
+ throw new Error (`Unable to parse db port ${process.env["DATABASE_PORT"]}`);
392
+ }
393
+ }
394
+ };
395
+
396
+ let serverType: string = "web";
397
+ let baseWebUrl: string = "";
398
+ let baseAPIUrl: string = "";
399
+ let runWebTestMap: boolean = false;
400
+ let runAPITestMap: boolean = false;
401
+
402
+ const runCmd: commander.Command = new commander.Command ("run");
403
+ runCmd.description (`Run commands.`);
404
+ runCmd.action (async () =>
405
+ {
406
+ let runWebServer: boolean = false;
407
+ let runAPIServer: boolean = false;
408
+ let testerServer: HotTesterServer = null;
409
+
410
+ if (processor.mode === DeveloperMode.Development)
411
+ {
412
+ let serverStarter = await HotTesterServer.startServer (
413
+ `http://${testerSettings.address}:${testerSettings.http}`, testerSettings.http, testerSettings.https, processor);
414
+ testerServer = serverStarter.server;
415
+
416
+ let tester: HotTester = null;
417
+
418
+ if (testerSettings.tester === "HotTesterMocha")
419
+ {
420
+ let mochaTester: HotTesterMocha = new HotTesterMocha (
421
+ processor, "HotTesterMocha", baseWebUrl, null);
422
+ tester = mochaTester;
423
+ }
424
+
425
+ if (testerSettings.tester === "HotTesterMochaSelenium")
426
+ {
427
+ let mochaSeleniumTester: HotTesterMochaSelenium = new HotTesterMochaSelenium (
428
+ processor, "HotTesterMochaSelenium", baseWebUrl);
429
+ mochaSeleniumTester.driver.browser = testerSettings.browser;
430
+ mochaSeleniumTester.driver.openDevTools = testerSettings.openDevTools;
431
+ mochaSeleniumTester.driver.headless = testerSettings.headless;
432
+ mochaSeleniumTester.driver.remoteServer = testerSettings.remoteServer;
433
+ tester = mochaSeleniumTester;
434
+ }
435
+
436
+ testerServer.addTester (tester);
437
+ }
438
+
439
+ if (hotsitePath !== "")
440
+ {
441
+ await processor.loadHotSite (hotsitePath);
442
+ apis = loadAPIs (processor);
443
+ }
444
+
445
+ // Setup the DB if it hasn't already been setup.
446
+ if (process.env["DATABASE_TYPE"] != null)
447
+ {
448
+ setupDB ();
449
+ dbinfo.type = process.env["DATABASE_TYPE"];
450
+ }
451
+
452
+ if (process.env["DATABASE_SERVER"] != null)
453
+ {
454
+ setupDB ();
455
+ dbinfo.server = process.env["DATABASE_SERVER"];
456
+ }
457
+
458
+ if (process.env["DATABASE_USERNAME"] != null)
459
+ {
460
+ setupDB ();
461
+ dbinfo.username = process.env["DATABASE_USERNAME"];
462
+ }
463
+
464
+ if (process.env["DATABASE_PASSWORD"] != null)
465
+ {
466
+ setupDB ();
467
+ dbinfo.password = process.env["DATABASE_PASSWORD"];
468
+ }
469
+
470
+ if (process.env["DATABASE_ORG"] != null)
471
+ {
472
+ setupDB ();
473
+ dbinfo.org = process.env["DATABASE_ORG"];
474
+ }
475
+
476
+ if (process.env["DATABASE_TOKEN"] != null)
477
+ {
478
+ setupDB ();
479
+ dbinfo.token = process.env["DATABASE_TOKEN"];
480
+ }
481
+
482
+ if (process.env["DATABASE_PORT"] != null)
483
+ {
484
+ setupDB ();
485
+
486
+ try
487
+ {
488
+ dbinfo.port = parseInt (process.env["DATABASE_PORT"]);
489
+ }
490
+ catch (ex)
491
+ {
492
+ throw new Error (`Unable to parse db port ${process.env["DATABASE_PORT"]}`);
493
+ }
494
+ }
495
+
496
+ if (process.env["DATABASE_SCHEMA"] != null)
497
+ {
498
+ setupDB ();
499
+ dbinfo.database = process.env["DATABASE_SCHEMA"];
500
+ }
501
+
502
+ if (baseWebUrl === "")
503
+ {
504
+ let foundBaseUrl: string = HotStaq.getValueFromHotSiteObj (processor.hotSite, ["server", "url"]);
505
+
506
+ if (foundBaseUrl != null)
507
+ baseWebUrl = foundBaseUrl;
508
+ }
509
+
510
+ if (baseWebUrl === "")
511
+ baseWebUrl = `http://127.0.0.1:${webServer.ports.http}`;
512
+
513
+ if ((serverType === "web") || (serverType === "web-api"))
514
+ {
515
+ if (processor.hotSite != null)
516
+ {
517
+ if (processor.hotSite.server != null)
518
+ processor.hotSite.server.url = baseWebUrl;
519
+ }
520
+
521
+ runWebServer = true;
522
+ }
523
+
524
+ if ((serverType === "api") || (serverType === "web-api"))
525
+ runAPIServer = true;
526
+
527
+ /// @fixme Allow for multiple APIs to be loaded, and have their
528
+ /// servers start in the future.
529
+ let getBaseUrlFromHotSite = (loadAPI: APItoLoad, baseUrl: string = ""): string =>
530
+ {
531
+ let foundAPIUrl: string = baseUrl;
532
+
533
+ // Attempt to find the base url from the HotSite's API.
534
+ if (processor.hotSite != null)
535
+ {
536
+ if (processor.hotSite.apis != null)
537
+ {
538
+ for (let key in processor.hotSite.apis)
539
+ {
540
+ let tempAPI = processor.hotSite.apis[key];
541
+
542
+ if (tempAPI.apiName != null)
543
+ {
544
+ if (tempAPI.apiName === loadAPI.exportedClassName)
545
+ {
546
+ if (tempAPI.url != null)
547
+ foundAPIUrl = tempAPI.url;
548
+
549
+ break;
550
+ }
551
+ }
552
+ }
553
+ }
554
+ }
555
+
556
+ return (foundAPIUrl);
557
+ };
558
+
559
+ let loadAndStartAPIServer = async (serverType: string) =>
560
+ {
561
+ if (Object.keys (apis).length < 1)
562
+ throw new Error (`No APIs are loaded! Try using --api-load`);
563
+
564
+ for (let key in apis)
565
+ {
566
+ let loadAPI: APItoLoad = apis[key];
567
+
568
+ if (baseAPIUrl === "")
569
+ baseAPIUrl = getBaseUrlFromHotSite (loadAPI);
570
+
571
+ if (baseAPIUrl === "")
572
+ baseAPIUrl = `http://127.0.0.1:${apiServer.ports.http}`;
573
+
574
+ // Only run the api server.
575
+ await startAPIServer (apiServer, loadAPI, baseAPIUrl, dbinfo, true);
576
+
577
+ if (globalLogLevel != null)
578
+ apiServer.logger.logLevel = globalLogLevel;
579
+
580
+ apiServer.serverType = serverType;
581
+ await apiServer.listen ();
582
+ }
583
+ };
584
+
585
+ if (serverType === "api")
586
+ await loadAndStartAPIServer ("API Server");
587
+
588
+ if (runWebServer === true)
589
+ {
590
+ if (runAPIServer === true)
591
+ await loadAndStartAPIServer ("Web-API Server");
592
+ else
593
+ webServer.serverType = "Web Server";
594
+
595
+ if (globalLogLevel != null)
596
+ webServer.logger.logLevel = globalLogLevel;
597
+
598
+ await webServer.listen ();
599
+ }
600
+
601
+ if (runWebTestMap === true)
602
+ {
603
+ if (testerServer == null)
604
+ throw new Error (`Unable to execute tests! Is --development-mode missing?`);
605
+
606
+ await testerServer.executeAllWebTests (testerSettings.tester);
607
+ }
608
+
609
+ if (runAPITestMap === true)
610
+ {
611
+ if (testerServer == null)
612
+ throw new Error (`Unable to execute tests! Is --development-mode missing?`);
613
+
614
+ await testerServer.executeAllAPITests (testerSettings.tester);
615
+ }
616
+ });
617
+
618
+ runCmd.option (`--tester-http-port <port>`,
619
+ `Set the tester HTTP port`,
620
+ (port: string, previous: any) =>
621
+ {
622
+ try
623
+ {
624
+ const tempPort: number = parseInt (port);
625
+
626
+ testerSettings.http = tempPort;
627
+ }
628
+ catch (ex)
629
+ {
630
+ processor.logger.error (`Unable to parse tester http port ${port}`);
631
+ }
632
+ }, testerSettings.http);
633
+ runCmd.option (`--tester-https-port <port>`,
634
+ `Set the tester HTTPS port`,
635
+ (port: string, previous: any) =>
636
+ {
637
+ if (port == null)
638
+ return;
639
+
640
+ if (port === "")
641
+ return;
642
+
643
+ try
644
+ {
645
+ const tempPort: number = parseInt (port);
646
+
647
+ testerSettings.https = tempPort;
648
+ }
649
+ catch (ex)
650
+ {
651
+ processor.logger.error (`Unable to parse tester https port ${port}`);
652
+ }
653
+ }, testerSettings.https);
654
+ runCmd.option (`--tester-type <tester>`,
655
+ `Set the tester to use. Can be: HotTesterMocha,HotTesterMochaSelenium`,
656
+ (tester: string, previous: any) =>
657
+ {
658
+ testerSettings.tester = tester;
659
+ }, "HotTesterMochaSelenium");
660
+ runCmd.option (`--tester-address <address>`,
661
+ `Set the tester address to listen on.`,
662
+ (address: string, previous: any) =>
663
+ {
664
+ testerSettings.address = address;
665
+ }, "127.0.0.1");
666
+ runCmd.option (`--tester-browser <browser>`,
667
+ `Set the tester browser to use. Can only be used with tester type: HotTesterMochaSelenium`,
668
+ (browser: string, previous: any) =>
669
+ {
670
+ testerSettings.browser = browser;
671
+ }, "chrome");
672
+ runCmd.option (`--tester-open-dev-tools`,
673
+ `Open the browsers dev tools on start. Can only be used with tester type: HotTesterMochaSelenium`,
674
+ (value: string, previous: any) =>
675
+ {
676
+ testerSettings.openDevTools = true;
677
+ }, "false");
678
+ runCmd.option (`--tester-headless`,
679
+ `Make the browser headless. Can only be used with tester type: HotTesterMochaSelenium`,
680
+ (value: string, previous: any) =>
681
+ {
682
+ testerSettings.headless = true;
683
+ }, "false");
684
+ runCmd.option (`--tester-remote-server <remote_server>`,
685
+ `Set the remote Selenium server to use for testing. Can only be used with tester type: HotTesterMochaSelenium`,
686
+ (remoteServer: string, previous: any) =>
687
+ {
688
+ testerSettings.remoteServer = remoteServer;
689
+ }, "");
690
+
691
+ const serverTypes: string[] = ["web", "api"];
692
+
693
+ for (let iIdx = 0; iIdx < serverTypes.length; iIdx++)
694
+ {
695
+ let currentServerType: string = serverTypes[iIdx];
696
+ let httpPort: number = 80;
697
+ let httpsPort: number = 443;
698
+
699
+ if (currentServerType === "api")
700
+ {
701
+ httpPort = 81;
702
+ httpsPort = 444;
703
+ }
704
+
705
+ runCmd.option (`--${currentServerType}-base-url <url>`,
706
+ `Set the base ${currentServerType} server url.`,
707
+ (url: string, previous: any) =>
708
+ {
709
+ if (currentServerType === "web")
710
+ baseWebUrl = url;
711
+ else
712
+ baseAPIUrl = url;
713
+ }, "");
714
+ runCmd.option (`--${currentServerType}-http-port <port>`,
715
+ `Set the ${currentServerType} HTTP port`,
716
+ (port: string, previous: any) =>
717
+ {
718
+ try
719
+ {
720
+ const tempPort: number = parseInt (port);
721
+
722
+ if (currentServerType === "web")
723
+ webServer.ports.http = tempPort;
724
+ else
725
+ apiServer.ports.http = tempPort;
726
+ }
727
+ catch (ex)
728
+ {
729
+ processor.logger.error (`Unable to parse ${currentServerType} http port ${port}`);
730
+ }
731
+ }, httpPort);
732
+ runCmd.option (`--${currentServerType}-https-port [port]`,
733
+ `Set the ${currentServerType} HTTPS port`,
734
+ (port: string, previous: any) =>
735
+ {
736
+ if (port == null)
737
+ return;
738
+
739
+ if (port === "")
740
+ return;
741
+
742
+ try
743
+ {
744
+ const tempPort: number = parseInt (port);
745
+
746
+ if (currentServerType === "web")
747
+ webServer.ports.https = tempPort;
748
+ else
749
+ apiServer.ports.https = tempPort;
750
+ }
751
+ catch (ex)
752
+ {
753
+ processor.logger.error (`Unable to parse ${currentServerType} https port ${port}`);
754
+ }
755
+ }, httpsPort);
756
+ runCmd.option (`--${currentServerType}-dont-redirect-http-to-https`,
757
+ `Do not redirect ${currentServerType} HTTP traffic to HTTPS`,
758
+ (port: string, previous: any) =>
759
+ {
760
+ if (currentServerType === "web")
761
+ webServer.redirectHTTPtoHTTPS = false;
762
+ else
763
+ apiServer.redirectHTTPtoHTTPS = false;
764
+ });
765
+ runCmd.option (`--${currentServerType}-listen-address <address>`,
766
+ `Set the ${currentServerType} listen address`,
767
+ (address: string, previous: any) =>
768
+ {
769
+ if (currentServerType === "web")
770
+ webServer.listenAddress = address;
771
+ else
772
+ apiServer.listenAddress = address;
773
+ }, "0.0.0.0");
774
+ runCmd.option (`--${currentServerType}-ssl-cert <path>`,
775
+ `Set the path to the SSL cert for the ${currentServerType} server`,
776
+ (cert: string, previous: any) =>
777
+ {
778
+ if (currentServerType === "web")
779
+ webServer.ssl.cert = cert;
780
+ else
781
+ apiServer.ssl.cert = cert;
782
+ }, "");
783
+ runCmd.option (`--${currentServerType}-ssl-key <path>`,
784
+ `Set the path to the SSL key for the ${currentServerType} server`,
785
+ (key: string, previous: any) =>
786
+ {
787
+ if (currentServerType === "web")
788
+ webServer.ssl.key = key;
789
+ else
790
+ apiServer.ssl.key = key;
791
+ }, "");
792
+ runCmd.option (`--${currentServerType}-ssl-ca <path>`,
793
+ `Set the path to the SSL CA for the ${currentServerType} server`,
794
+ (ca: string, previous: any) =>
795
+ {
796
+ if (currentServerType === "web")
797
+ webServer.ssl.ca = ca;
798
+ else
799
+ apiServer.ssl.ca = ca;
800
+ }, "");
801
+ runCmd.option (`--${currentServerType}-log-level <level>`,
802
+ `Set the logging level for the ${currentServerType} server. Can be (info,warning,error,all,none)`,
803
+ (logLevel: string, previous: any) =>
804
+ {
805
+ let tempServer: HotHTTPServer = null;
806
+
807
+ if (logLevel === "")
808
+ return;
809
+
810
+ if (currentServerType === "web")
811
+ tempServer = webServer;
812
+ else
813
+ tempServer = apiServer;
814
+
815
+ if (logLevel === "info")
816
+ tempServer.logger.logLevel = HotLogLevel.Info;
817
+
818
+ if (logLevel === "warning")
819
+ tempServer.logger.logLevel = HotLogLevel.Warning;
820
+
821
+ if (logLevel === "error")
822
+ tempServer.logger.logLevel = HotLogLevel.Error;
823
+
824
+ if (logLevel === "verbose")
825
+ tempServer.logger.logLevel = HotLogLevel.Verbose;
826
+
827
+ if (logLevel === "all")
828
+ tempServer.logger.logLevel = HotLogLevel.All;
829
+
830
+ if (logLevel === "none")
831
+ tempServer.logger.logLevel = HotLogLevel.None;
832
+ }, "");
833
+ runCmd.option (`--${currentServerType}-test`,
834
+ `Execute all tests specified in HotSite.json. Must be used with --development-mode.`,
835
+ (map: string, previous: any) =>
836
+ {
837
+ if (currentServerType === "web")
838
+ runWebTestMap = true;
839
+ else
840
+ runAPITestMap = true;
841
+ });
842
+
843
+ if (currentServerType === "web")
844
+ {
845
+ runCmd.option (`--${currentServerType}-route <route_and_path>`,
846
+ `Add a static route in "key=path" format. Example: --${currentServerType}-route "/=/var/www"`,
847
+ (routeAndPath: string, previous: any) =>
848
+ {
849
+ let keyValuePair = getKeyValuePair (routeAndPath);
850
+ const route: string = keyValuePair.key;
851
+ const path: string = keyValuePair.value;
852
+
853
+ webServer.addStaticRoute (route, path);
854
+ });
855
+ runCmd.option (`--${currentServerType}-serve-hott-files`, "Serve Hott files",
856
+ (port: string, previous: any) =>
857
+ {
858
+ webServer.serveHottFiles = true;
859
+ });
860
+ runCmd.option (`--${currentServerType}-js-url <url>`, "The url to the HotStaq JS",
861
+ (url: string, previous: any) =>
862
+ {
863
+ webServer.hottFilesAssociatedInfo.jsSrcPath = url;
864
+ });
865
+ }
866
+
867
+ if (currentServerType === "api")
868
+ {
869
+ runCmd.option (`--${currentServerType}-load <exported_name_and_path>`,
870
+ `Load an API for use in "exported_name=path_to_js_file" format. Example: --${currentServerType}-load "FreeLightAPI=/app/FreeLight/build/src/FreeLightAPI.js"`,
871
+ (exported_name_and_path: string, previous: any) =>
872
+ {
873
+ let keyValuePair = getKeyValuePair (exported_name_and_path);
874
+ const exportedClassName: string = keyValuePair.key;
875
+ const path: string = keyValuePair.value;
876
+
877
+ apis[exportedClassName] = { exportedClassName: exportedClassName, path: path };
878
+ });
879
+ }
880
+ }
881
+
882
+ runCmd.option (`--server-type <type>`,
883
+ `Set the type of server. Can be (web, api, web-api)`,
884
+ (type: string, previous: any) =>
885
+ {
886
+ serverType = type;
887
+ }, "web");
888
+ runCmd.option ("--db-type <type>", "The type of database to use. Can be (mysql, influx)",
889
+ (type: string, previous: any) =>
890
+ {
891
+ setupDB ();
892
+ dbinfo.type = type;
893
+ }, "mysql");
894
+ runCmd.option ("--db-server <address>", "The address to the database",
895
+ (address: string, previous: any) =>
896
+ {
897
+ setupDB ();
898
+ dbinfo.server = address;
899
+ }, "127.0.0.1");
900
+ runCmd.option ("--db-username <username>", "The database's username",
901
+ (username: string, previous: any) =>
902
+ {
903
+ setupDB ();
904
+ dbinfo.username = username;
905
+ });
906
+ runCmd.option ("--db-password <password>", "The database's password. This is insecure to use on the command line!",
907
+ (password: string, previous: any) =>
908
+ {
909
+ setupDB ();
910
+ dbinfo.password = password;
911
+ });
912
+ runCmd.option ("--db-port <port>", "The database's port",
913
+ (port: string, previous: any) =>
914
+ {
915
+ setupDB ();
916
+
917
+ try
918
+ {
919
+ dbinfo.port = parseInt (port);
920
+ }
921
+ catch (ex)
922
+ {
923
+ processor.logger.error (`Unable to parse db port ${port}`);
924
+ }
925
+ }, "3306");
926
+ runCmd.option ("--db-database <schema>", "The database's schema to select",
927
+ (schema: string, previous: any) =>
928
+ {
929
+ setupDB ();
930
+ dbinfo.database = schema;
931
+ });
932
+
933
+ return (runCmd);
934
+ }
935
+
936
+ /**
937
+ * Handle any agent commands.
938
+ */
939
+ async function handleAgentCommands (): Promise<commander.Command>
940
+ {
941
+ let baseAPIUrl: string = "";
942
+ let agentKey: string = "";
943
+ let agentSecret: string = "";
944
+ let commands: { [name: string]: string } = {};
945
+ let listenAddr: string = "0.0.0.0";
946
+ let port: number = 5468;
947
+
948
+ const agentCmd: commander.Command = new commander.Command ("agent");
949
+ agentCmd.description (`Listen for commands on a port.`);
950
+ agentCmd.action (async () =>
951
+ {
952
+ let processor: HotStaq = new HotStaq ();
953
+ processor.logger.logLevel = HotLogLevel.Verbose;
954
+
955
+ let apiServer: HotHTTPServer = new HotHTTPServer (processor);
956
+ let api: HotAgentAPI = new HotAgentAPI (baseAPIUrl, apiServer);
957
+ api.key = agentKey;
958
+ api.secret = agentSecret;
959
+ apiServer.listenAddress = listenAddr;
960
+ apiServer.ports.http = port;
961
+ apiServer.processor.api = api;
962
+ apiServer.api = api;
963
+ await apiServer.setAPI (api);
964
+
965
+ await apiServer.listen ();
966
+ });
967
+
968
+ agentCmd.option ("--base_api_url <value>", "The key that must be given in order to execute the commands.",
969
+ (value: string, previous: any) =>
970
+ {
971
+ baseAPIUrl = value;
972
+ });
973
+ agentCmd.option ("--key <key>", "The key that must be given in order to execute the commands.",
974
+ (value: string, previous: any) =>
975
+ {
976
+ agentKey = value;
977
+ });
978
+ agentCmd.option ("--secret <secret>", "The secret key that must be given in order to execute the commands.",
979
+ (value: string, previous: any) =>
980
+ {
981
+ agentSecret = value;
982
+ });
983
+ agentCmd.option ("--file <key_filepath>", "The key and the associated NodeJS file to execute (key=path).",
984
+ (value: string, previous: any) =>
985
+ {
986
+ let key: string = "";
987
+ let filepath: string = "";
988
+ let pos: number = key.indexOf ("=");
989
+
990
+ if (pos < 0)
991
+ throw new Error (`key_filepath must be in the format (key=path)`);
992
+
993
+ key = value.substr (0, pos);
994
+ filepath = value.substr (pos + 1);
995
+
996
+ commands[key] = filepath;
997
+ });
998
+ agentCmd.option ("--listen-addr <addr>", "The address to listen on.",
999
+ (value: string, previous: any) =>
1000
+ {
1001
+ listenAddr = value;
1002
+ });
1003
+ agentCmd.option ("--listen-port <port>", "The port to listen on.",
1004
+ (value: string, previous: any) =>
1005
+ {
1006
+ try
1007
+ {
1008
+ port = parseInt (value);
1009
+ }
1010
+ catch (ex)
1011
+ {
1012
+ throw new Error (`Unable to parse port ${value}`);
1013
+ }
1014
+ });
1015
+
1016
+ return (agentCmd);
1017
+ }
1018
+
1019
+ /**
1020
+ * Handle any generate commands.
1021
+ */
1022
+ async function handleGenerateCommands (): Promise<commander.Command>
1023
+ {
1024
+ let generator: HotGenerator = null;
1025
+ let createHotBuilder = () =>
1026
+ {
1027
+ if (generator == null)
1028
+ generator = new HotGenerator (processor.logger);
1029
+ };
1030
+
1031
+ const generateCmd: commander.Command = new commander.Command ("generate");
1032
+ generateCmd.description (`API Generation commands.`);
1033
+ generateCmd.action (async () =>
1034
+ {
1035
+ createHotBuilder ();
1036
+
1037
+ if (hotsitePath === "")
1038
+ {
1039
+ let tempHotsitePath: string = ppath.normalize (`${process.cwd ()}/HotSite.json`);
1040
+
1041
+ /// @fixme Do this check without caps sensitivity.
1042
+ if (await HotIO.exists (tempHotsitePath) === true)
1043
+ hotsitePath = tempHotsitePath;
1044
+ }
1045
+
1046
+ if (hotsitePath === "")
1047
+ throw new Error (`When building, you must specify a HotSite.json!`);
1048
+
1049
+ let apis: { [name: string]: APItoLoad; } = {};
1050
+
1051
+ if (hotsitePath !== "")
1052
+ {
1053
+ await processor.loadHotSite (hotsitePath);
1054
+ apis = loadAPIs (processor);
1055
+ }
1056
+
1057
+ generator.hotsites = [processor.hotSite];
1058
+ await generator.generateAPI (processor, apis);
1059
+ });
1060
+
1061
+ generateCmd.option ("--tsconfig <path>", "Specify the tsconfig.json file to use.",
1062
+ (arg: string, previous: any) =>
1063
+ {
1064
+ createHotBuilder ();
1065
+ generator.tsconfigPath = arg;
1066
+ });
1067
+ generateCmd.option ("--webpack-config <path>", "Specify the webpack config javascript file to use.",
1068
+ (arg: string, previous: any) =>
1069
+ {
1070
+ createHotBuilder ();
1071
+ generator.webpackConfigPath = arg;
1072
+ });
1073
+ generateCmd.option ("--optimize", "Optimize the compiled JavaScript using the Google Closure Compiler.",
1074
+ (arg: string, previous: any) =>
1075
+ {
1076
+ createHotBuilder ();
1077
+ generator.optimizeJS = true;
1078
+ });
1079
+ generateCmd.option ("--generate-type <type>", "The type of output to generate. Can be: typescript,javascript",
1080
+ (arg: string, previous: any) =>
1081
+ {
1082
+ createHotBuilder ();
1083
+ generator.generateType = arg;
1084
+ });
1085
+ generateCmd.option ("--output <path>", "The directory path to place all files.",
1086
+ (arg: string, previous: any) =>
1087
+ {
1088
+ createHotBuilder ();
1089
+ generator.outputDir = arg;
1090
+ });
1091
+
1092
+ return (generateCmd);
1093
+ }
1094
+
1095
+ /**
1096
+ * Check if the path exists.
1097
+ */
1098
+ function checkIfPathExists (path: string): boolean
1099
+ {
1100
+ if (fs.existsSync (path) === true)
1101
+ return (true);
1102
+
1103
+ return (false);
1104
+ }
1105
+
1106
+ /**
1107
+ * Start the CLI app.
1108
+ */
1109
+ async function start ()
1110
+ {
1111
+ try
1112
+ {
1113
+ let packagePath: string = ppath.normalize (`${__dirname}/../../package.json`);
1114
+
1115
+ if (checkIfPathExists (packagePath) === false)
1116
+ {
1117
+ packagePath = ppath.normalize (`${process.cwd ()}/package.json`);
1118
+
1119
+ if (checkIfPathExists (packagePath) === false)
1120
+ {
1121
+ console.error (`Unable to find path to HotStaq!`);
1122
+
1123
+ return;
1124
+ }
1125
+ }
1126
+
1127
+ let packageJSON: any = JSON.parse (fs.readFileSync (packagePath).toString ());
1128
+ VERSION = packageJSON.version;
1129
+
1130
+ const program: commander.Command = new commander.Command ("hotstaq");
1131
+
1132
+ program.description (`Copyright(c) 2021, FreeLight, Inc. Under the MIT License.`);
1133
+ let command: commander.Command = program.version (VERSION);
1134
+
1135
+ let hotsiteExists: boolean = false;
1136
+ let foundHotsitePath: string = "";
1137
+
1138
+ if (checkIfPathExists ("./HotSite.json") === true)
1139
+ {
1140
+ hotsiteExists = true;
1141
+ foundHotsitePath = ppath.normalize ("./HotSite.json");
1142
+ }
1143
+
1144
+ if (checkIfPathExists ("./hotsite.json") === true)
1145
+ {
1146
+ hotsiteExists = true;
1147
+ foundHotsitePath = ppath.normalize ("./HotSite.json");
1148
+ }
1149
+
1150
+ if (hotsiteExists === true)
1151
+ hotsitePath = foundHotsitePath;
1152
+
1153
+ command.option ("--cwd <path>", "Set the current working directory to use.",
1154
+ (path: string, previous: any) =>
1155
+ {
1156
+ process.chdir (path);
1157
+ });
1158
+ command.option ("-o, --hotsite <path>", "Specify the HotSite.json to use. This will look in the current directory to find one first.",
1159
+ (path: string, previous: any) =>
1160
+ {
1161
+ hotsitePath = path;
1162
+ }, foundHotsitePath);
1163
+ command.option ("--not-hot", "Do not use a HotSite.json.",
1164
+ (path: string, previous: any) =>
1165
+ {
1166
+ hotsitePath = "";
1167
+ });
1168
+ command.option ("--verbose", "Set the logging level to verbose.",
1169
+ (logLevel: string, previous: any) =>
1170
+ {
1171
+ if (logLevel === "verbose")
1172
+ globalLogLevel = HotLogLevel.Verbose;
1173
+ });
1174
+ command.option ("-l, --log-level <level>", "Set the logging level. Can be (info,warning,error,all,none)",
1175
+ (logLevel: string, previous: any) =>
1176
+ {
1177
+ if (logLevel === "info")
1178
+ globalLogLevel = HotLogLevel.Info;
1179
+
1180
+ if (logLevel === "warning")
1181
+ globalLogLevel = HotLogLevel.Warning;
1182
+
1183
+ if (logLevel === "error")
1184
+ globalLogLevel = HotLogLevel.Error;
1185
+
1186
+ if (logLevel === "verbose")
1187
+ globalLogLevel = HotLogLevel.Verbose;
1188
+
1189
+ if (logLevel === "all")
1190
+ globalLogLevel = HotLogLevel.All;
1191
+
1192
+ if (logLevel === "none")
1193
+ globalLogLevel = HotLogLevel.None;
1194
+ }, "");
1195
+ command.option ("--dev, --development-mode", "Set to execute in development mode. This will allow for testing data to be collected and executed",
1196
+ (value: string, previous: any) =>
1197
+ {
1198
+ processor.mode = DeveloperMode.Development;
1199
+ });
1200
+
1201
+ let createCmd: commander.Command = await handleCreateCommands ();
1202
+ command.addCommand (createCmd);
1203
+
1204
+ let runCmd: commander.Command = await handleRunCommands ();
1205
+ command.addCommand (runCmd);
1206
+
1207
+ let buildCmd: commander.Command = await handleBuildCommands ();
1208
+ command.addCommand (buildCmd);
1209
+
1210
+ let generateCmd: commander.Command = await handleGenerateCommands ();
1211
+ command.addCommand (generateCmd);
1212
+
1213
+ let agentCmd: commander.Command = await handleAgentCommands ();
1214
+ command.addCommand (agentCmd);
1215
+
1216
+ if (process.argv.length > 2)
1217
+ program.parse (process.argv);
1218
+ }
1219
+ catch (ex)
1220
+ {
1221
+ processor.logger.error (ex.stack);
1222
+ }
1223
+ }
1224
+
1225
+ start ();