@harperfast/harper 5.0.0-alpha.10 → 5.0.0-beta.1

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 (444) hide show
  1. package/bin/BinObjects.js +17 -0
  2. package/bin/cliOperations.js +157 -0
  3. package/bin/copyDb.ts +280 -0
  4. package/bin/harper.js +156 -0
  5. package/bin/install.js +15 -0
  6. package/bin/lite.js +5 -0
  7. package/bin/restart.js +201 -0
  8. package/bin/run.js +409 -0
  9. package/bin/status.js +65 -0
  10. package/bin/stop.js +22 -0
  11. package/bin/upgrade.js +134 -0
  12. package/components/Application.ts +646 -0
  13. package/components/ApplicationScope.ts +49 -0
  14. package/components/Component.ts +53 -0
  15. package/components/ComponentV1.ts +342 -0
  16. package/components/DEFAULT_CONFIG.ts +18 -0
  17. package/components/EntryHandler.ts +227 -0
  18. package/components/Logger.ts +14 -0
  19. package/components/OptionsWatcher.ts +354 -0
  20. package/components/PluginModule.ts +6 -0
  21. package/components/Scope.ts +329 -0
  22. package/components/componentLoader.ts +529 -0
  23. package/components/deriveCommonPatternBase.ts +31 -0
  24. package/components/deriveGlobOptions.ts +44 -0
  25. package/components/deriveURLPath.ts +57 -0
  26. package/components/operations.js +658 -0
  27. package/components/operationsValidation.js +246 -0
  28. package/components/packageComponent.ts +39 -0
  29. package/components/requestRestart.ts +26 -0
  30. package/components/resolveBaseURLPath.ts +38 -0
  31. package/components/status/ComponentStatus.ts +110 -0
  32. package/components/status/ComponentStatusRegistry.ts +251 -0
  33. package/components/status/api.ts +153 -0
  34. package/components/status/crossThread.ts +405 -0
  35. package/components/status/errors.ts +152 -0
  36. package/components/status/index.ts +44 -0
  37. package/components/status/internal.ts +65 -0
  38. package/components/status/registry.ts +12 -0
  39. package/components/status/types.ts +96 -0
  40. package/config/RootConfigWatcher.ts +59 -0
  41. package/config/configHelpers.ts +11 -0
  42. package/config/configUtils.js +967 -0
  43. package/config/harperConfigEnvVars.ts +641 -0
  44. package/dataLayer/CreateAttributeObject.js +25 -0
  45. package/dataLayer/CreateTableObject.js +11 -0
  46. package/dataLayer/DataLayerObjects.js +43 -0
  47. package/dataLayer/DeleteBeforeObject.js +22 -0
  48. package/dataLayer/DeleteObject.js +25 -0
  49. package/dataLayer/DropAttributeObject.js +11 -0
  50. package/dataLayer/GetBackupObject.js +22 -0
  51. package/dataLayer/InsertObject.js +24 -0
  52. package/dataLayer/ReadAuditLogObject.js +24 -0
  53. package/dataLayer/SQLSearch.js +1335 -0
  54. package/dataLayer/SearchByConditionsObject.js +61 -0
  55. package/dataLayer/SearchByHashObject.js +21 -0
  56. package/dataLayer/SearchObject.js +45 -0
  57. package/dataLayer/SqlSearchObject.js +14 -0
  58. package/dataLayer/UpdateObject.js +23 -0
  59. package/dataLayer/UpsertObject.js +23 -0
  60. package/dataLayer/bulkLoad.js +813 -0
  61. package/dataLayer/dataObjects/BulkLoadObjects.js +27 -0
  62. package/dataLayer/dataObjects/UpsertObject.js +23 -0
  63. package/dataLayer/delete.js +164 -0
  64. package/dataLayer/export.js +381 -0
  65. package/dataLayer/getBackup.js +40 -0
  66. package/dataLayer/harperBridge/BridgeMethods.js +81 -0
  67. package/dataLayer/harperBridge/ResourceBridge.ts +633 -0
  68. package/dataLayer/harperBridge/bridgeUtility/insertUpdateReturnObj.js +28 -0
  69. package/dataLayer/harperBridge/bridgeUtility/insertUpdateValidate.js +88 -0
  70. package/dataLayer/harperBridge/harperBridge.js +21 -0
  71. package/dataLayer/harperBridge/lmdbBridge/LMDBBridge.js +119 -0
  72. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +19 -0
  73. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateAttribute.js +112 -0
  74. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateRecords.js +67 -0
  75. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateSchema.js +31 -0
  76. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateTable.js +94 -0
  77. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteAuditLogsBefore.js +98 -0
  78. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteRecords.js +89 -0
  79. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropAttribute.js +109 -0
  80. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropSchema.js +107 -0
  81. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropTable.js +137 -0
  82. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbFlush.js +35 -0
  83. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetBackup.js +111 -0
  84. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByHash.js +28 -0
  85. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByValue.js +29 -0
  86. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbReadAuditLog.js +207 -0
  87. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByConditions.js +156 -0
  88. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByHash.js +21 -0
  89. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByValue.js +30 -0
  90. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbTransaction.js +19 -0
  91. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpdateRecords.js +64 -0
  92. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpsertRecords.js +70 -0
  93. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBCreateAttributeObject.js +22 -0
  94. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBDeleteTransactionObject.js +23 -0
  95. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBInsertTransactionObject.js +22 -0
  96. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBTransactionObject.js +23 -0
  97. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpdateTransactionObject.js +24 -0
  98. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpsertTransactionObject.js +24 -0
  99. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js +25 -0
  100. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializeHashSearch.js +21 -0
  101. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +157 -0
  102. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbCheckForNewAttributes.js +94 -0
  103. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbCreateTransactionsAuditEnvironment.js +39 -0
  104. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js +34 -0
  105. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbProcessRows.js +100 -0
  106. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbSearch.js +371 -0
  107. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbWriteTransaction.js +109 -0
  108. package/dataLayer/hdbInfoController.js +254 -0
  109. package/dataLayer/insert.js +266 -0
  110. package/dataLayer/readAuditLog.js +59 -0
  111. package/dataLayer/schema.js +366 -0
  112. package/dataLayer/schemaDescribe.js +289 -0
  113. package/dataLayer/search.js +60 -0
  114. package/dataLayer/transaction.js +17 -0
  115. package/dataLayer/update.js +124 -0
  116. package/dist/components/Logger.d.ts +12 -0
  117. package/dist/components/Logger.js +3 -0
  118. package/dist/components/Logger.js.map +1 -0
  119. package/dist/components/Scope.d.ts +14 -4
  120. package/dist/components/Scope.js +18 -10
  121. package/dist/components/Scope.js.map +1 -1
  122. package/dist/components/componentLoader.js +16 -9
  123. package/dist/components/componentLoader.js.map +1 -1
  124. package/dist/components/operations.js +2 -2
  125. package/dist/components/operations.js.map +1 -1
  126. package/dist/config/configUtils.d.ts +1 -1
  127. package/dist/config/configUtils.js +1 -1
  128. package/dist/config/configUtils.js.map +1 -1
  129. package/dist/dataLayer/CreateTableObject.d.ts +2 -2
  130. package/dist/dataLayer/CreateTableObject.js +2 -2
  131. package/dist/dataLayer/CreateTableObject.js.map +1 -1
  132. package/dist/dataLayer/delete.d.ts +1 -1
  133. package/dist/dataLayer/schema.js +6 -5
  134. package/dist/dataLayer/schema.js.map +1 -1
  135. package/dist/dataLayer/schemaDescribe.js +1 -1
  136. package/dist/dataLayer/schemaDescribe.js.map +1 -1
  137. package/dist/index.d.ts +1 -1
  138. package/dist/index.js +2 -0
  139. package/dist/index.js.map +1 -1
  140. package/dist/resources/DatabaseTransaction.d.ts +1 -1
  141. package/dist/resources/IterableEventQueue.d.ts +1 -1
  142. package/dist/resources/LMDBTransaction.d.ts +5 -1
  143. package/dist/resources/Resource.d.ts +1 -1
  144. package/dist/resources/RocksIndexStore.d.ts +3 -3
  145. package/dist/resources/RocksTransactionLogStore.d.ts +6 -3
  146. package/dist/resources/Table.d.ts +15 -6
  147. package/dist/resources/Table.js +4 -1
  148. package/dist/resources/Table.js.map +1 -1
  149. package/dist/resources/analytics/read.js +32 -22
  150. package/dist/resources/analytics/read.js.map +1 -1
  151. package/dist/resources/analytics/write.js +3 -6
  152. package/dist/resources/analytics/write.js.map +1 -1
  153. package/dist/resources/auditStore.d.ts +3 -3
  154. package/dist/resources/blob.d.ts +25 -2
  155. package/dist/resources/databases.d.ts +12 -2
  156. package/dist/resources/databases.js +22 -19
  157. package/dist/resources/databases.js.map +1 -1
  158. package/dist/resources/search.js +11 -5
  159. package/dist/resources/search.js.map +1 -1
  160. package/dist/resources/transaction.d.ts +2 -1
  161. package/dist/security/auth.js +1 -1
  162. package/dist/security/auth.js.map +1 -1
  163. package/dist/security/cryptoHash.d.ts +2 -2
  164. package/dist/security/jsLoader.js +243 -66
  165. package/dist/security/jsLoader.js.map +1 -1
  166. package/dist/security/keys.js +4 -5
  167. package/dist/security/keys.js.map +1 -1
  168. package/dist/security/user.js +3 -3
  169. package/dist/security/user.js.map +1 -1
  170. package/dist/server/REST.js +16 -2
  171. package/dist/server/REST.js.map +1 -1
  172. package/dist/server/Server.d.ts +2 -1
  173. package/dist/server/Server.js.map +1 -1
  174. package/dist/server/fastifyRoutes/plugins/hdbCore.d.ts +6 -1
  175. package/dist/server/fastifyRoutes.js +2 -0
  176. package/dist/server/fastifyRoutes.js.map +1 -1
  177. package/dist/server/http.js +12 -6
  178. package/dist/server/http.js.map +1 -1
  179. package/dist/server/jobs/JobObject.d.ts +3 -3
  180. package/dist/server/loadRootComponents.js +1 -0
  181. package/dist/server/loadRootComponents.js.map +1 -1
  182. package/dist/server/operationsServer.js +3 -1
  183. package/dist/server/operationsServer.js.map +1 -1
  184. package/dist/server/serverHelpers/JSONStream.d.ts +3 -3
  185. package/dist/server/serverHelpers/Request.d.ts +5 -5
  186. package/dist/server/serverHelpers/requestTimePlugin.d.ts +1 -1
  187. package/dist/server/threads/manageThreads.d.ts +2 -2
  188. package/dist/server/threads/manageThreads.js +50 -35
  189. package/dist/server/threads/manageThreads.js.map +1 -1
  190. package/dist/server/threads/socketRouter.d.ts +1 -1
  191. package/dist/sqlTranslator/deleteTranslator.d.ts +1 -1
  192. package/dist/utility/AWS/AWSConnector.d.ts +3 -2
  193. package/dist/utility/common_utils.d.ts +3 -3
  194. package/dist/utility/environment/systemInformation.d.ts +1 -0
  195. package/dist/utility/functions/date/dateFunctions.d.ts +11 -11
  196. package/dist/utility/globalSchema.d.ts +1 -1
  197. package/dist/utility/hdbTerms.d.ts +3 -0
  198. package/dist/utility/hdbTerms.js +3 -0
  199. package/dist/utility/hdbTerms.js.map +1 -1
  200. package/dist/utility/installation.d.ts +2 -4
  201. package/dist/utility/installation.js.map +1 -1
  202. package/dist/utility/lmdb/commonUtility.d.ts +1 -0
  203. package/dist/utility/lmdb/deleteUtility.d.ts +1 -0
  204. package/dist/utility/lmdb/environmentUtility.d.ts +1 -0
  205. package/dist/utility/lmdb/searchUtility.d.ts +2 -1
  206. package/dist/utility/lmdb/writeUtility.d.ts +1 -0
  207. package/dist/utility/logging/harper_logger.d.ts +6 -6
  208. package/dist/utility/processManagement/processManagement.d.ts +1 -1
  209. package/dist/utility/processManagement/servicesConfig.d.ts +12 -6
  210. package/dist/validation/common_validators.d.ts +4 -3
  211. package/dist/validation/configValidator.d.ts +3 -2
  212. package/index.d.ts +56 -0
  213. package/index.js +41 -0
  214. package/json/systemSchema.json +373 -0
  215. package/launchServiceScripts/launchHarperDB.js +3 -0
  216. package/launchServiceScripts/utility/checkNodeVersion.js +15 -0
  217. package/package.json +21 -3
  218. package/resources/DatabaseTransaction.ts +378 -0
  219. package/resources/ErrorResource.ts +57 -0
  220. package/resources/IterableEventQueue.ts +94 -0
  221. package/resources/LMDBTransaction.ts +349 -0
  222. package/resources/RecordEncoder.ts +702 -0
  223. package/resources/RequestTarget.ts +134 -0
  224. package/resources/Resource.ts +789 -0
  225. package/resources/ResourceInterface.ts +221 -0
  226. package/resources/ResourceInterfaceV2.ts +53 -0
  227. package/resources/ResourceV2.ts +67 -0
  228. package/resources/Resources.ts +162 -0
  229. package/resources/RocksIndexStore.ts +70 -0
  230. package/resources/RocksTransactionLogStore.ts +352 -0
  231. package/resources/Table.ts +4527 -0
  232. package/resources/analytics/hostnames.ts +72 -0
  233. package/resources/analytics/metadata.ts +10 -0
  234. package/resources/analytics/read.ts +252 -0
  235. package/resources/analytics/write.ts +803 -0
  236. package/resources/auditStore.ts +556 -0
  237. package/resources/blob.ts +1268 -0
  238. package/resources/crdt.ts +125 -0
  239. package/resources/dataLoader.ts +527 -0
  240. package/resources/databases.ts +1290 -0
  241. package/resources/graphql.ts +221 -0
  242. package/resources/indexes/HierarchicalNavigableSmallWorld.ts +638 -0
  243. package/resources/indexes/customIndexes.ts +7 -0
  244. package/resources/indexes/vector.ts +38 -0
  245. package/resources/jsResource.ts +86 -0
  246. package/resources/loadEnv.ts +22 -0
  247. package/resources/login.ts +18 -0
  248. package/resources/openApi.ts +409 -0
  249. package/resources/registrationDeprecated.ts +8 -0
  250. package/resources/replayLogs.ts +136 -0
  251. package/resources/roles.ts +98 -0
  252. package/resources/search.ts +1301 -0
  253. package/resources/tracked.ts +584 -0
  254. package/resources/transaction.ts +89 -0
  255. package/resources/transactionBroadcast.ts +258 -0
  256. package/security/auth.ts +376 -0
  257. package/security/certificateVerification/certificateVerificationSource.ts +84 -0
  258. package/security/certificateVerification/configValidation.ts +107 -0
  259. package/security/certificateVerification/crlVerification.ts +623 -0
  260. package/security/certificateVerification/index.ts +121 -0
  261. package/security/certificateVerification/ocspVerification.ts +148 -0
  262. package/security/certificateVerification/pkijs-ed25519-patch.ts +188 -0
  263. package/security/certificateVerification/types.ts +128 -0
  264. package/security/certificateVerification/verificationConfig.ts +138 -0
  265. package/security/certificateVerification/verificationUtils.ts +447 -0
  266. package/security/cryptoHash.js +42 -0
  267. package/security/data_objects/PermissionAttributeResponseObject.js +15 -0
  268. package/security/data_objects/PermissionResponseObject.js +115 -0
  269. package/security/data_objects/PermissionTableResponseObject.js +20 -0
  270. package/security/fastifyAuth.js +169 -0
  271. package/security/impersonation.ts +160 -0
  272. package/security/jsLoader.ts +716 -0
  273. package/security/keys.js +948 -0
  274. package/security/permissionsTranslator.js +300 -0
  275. package/security/role.js +218 -0
  276. package/security/tokenAuthentication.ts +228 -0
  277. package/security/user.ts +449 -0
  278. package/server/DurableSubscriptionsSession.ts +503 -0
  279. package/server/REST.ts +407 -0
  280. package/server/Server.ts +89 -0
  281. package/server/fastifyRoutes/helpers/getCORSOptions.js +36 -0
  282. package/server/fastifyRoutes/helpers/getHeaderTimeoutConfig.js +15 -0
  283. package/server/fastifyRoutes/helpers/getServerOptions.js +33 -0
  284. package/server/fastifyRoutes/plugins/hdbCore.js +39 -0
  285. package/server/fastifyRoutes.ts +205 -0
  286. package/server/graphqlQuerying.ts +700 -0
  287. package/server/http.ts +640 -0
  288. package/server/itc/serverHandlers.js +161 -0
  289. package/server/itc/utility/ITCEventObject.js +10 -0
  290. package/server/jobs/JobObject.js +24 -0
  291. package/server/jobs/jobProcess.js +69 -0
  292. package/server/jobs/jobRunner.js +162 -0
  293. package/server/jobs/jobs.js +304 -0
  294. package/server/loadRootComponents.js +44 -0
  295. package/server/mqtt.ts +485 -0
  296. package/server/nodeName.ts +75 -0
  297. package/server/operationsServer.ts +313 -0
  298. package/server/serverHelpers/Headers.ts +108 -0
  299. package/server/serverHelpers/JSONStream.ts +269 -0
  300. package/server/serverHelpers/OperationFunctionObject.ts +13 -0
  301. package/server/serverHelpers/Request.ts +158 -0
  302. package/server/serverHelpers/contentTypes.ts +637 -0
  303. package/server/serverHelpers/requestTimePlugin.js +57 -0
  304. package/server/serverHelpers/serverHandlers.js +148 -0
  305. package/server/serverHelpers/serverUtilities.ts +473 -0
  306. package/server/serverRegistry.ts +8 -0
  307. package/server/static.ts +187 -0
  308. package/server/status/definitions.ts +37 -0
  309. package/server/status/index.ts +125 -0
  310. package/server/storageReclamation.ts +93 -0
  311. package/server/threads/itc.js +89 -0
  312. package/server/threads/manageThreads.js +594 -0
  313. package/server/threads/socketRouter.ts +360 -0
  314. package/server/threads/threadServer.js +279 -0
  315. package/server/throttle.ts +73 -0
  316. package/sqlTranslator/SelectValidator.js +330 -0
  317. package/sqlTranslator/alasqlFunctionImporter.js +62 -0
  318. package/sqlTranslator/deleteTranslator.js +67 -0
  319. package/sqlTranslator/index.js +242 -0
  320. package/sqlTranslator/sql_statement_bucket.js +472 -0
  321. package/static/defaultConfig.yaml +3 -0
  322. package/studio/web/HDBDogOnly.svg +78 -0
  323. package/studio/web/assets/PPRadioGrotesk-Bold-DDaUYG8E.woff +0 -0
  324. package/studio/web/assets/fa-brands-400-CEJbCg16.woff +0 -0
  325. package/studio/web/assets/fa-brands-400-CSYNqBb_.ttf +0 -0
  326. package/studio/web/assets/fa-brands-400-DnkPfk3o.eot +0 -0
  327. package/studio/web/assets/fa-brands-400-UxlILjvJ.woff2 +0 -0
  328. package/studio/web/assets/fa-brands-400-cH1MgKbP.svg +3717 -0
  329. package/studio/web/assets/fa-regular-400-BhTwtT8w.eot +0 -0
  330. package/studio/web/assets/fa-regular-400-D1vz6WBx.ttf +0 -0
  331. package/studio/web/assets/fa-regular-400-DFnMcJPd.woff +0 -0
  332. package/studio/web/assets/fa-regular-400-DGzu1beS.woff2 +0 -0
  333. package/studio/web/assets/fa-regular-400-gwj8Pxq-.svg +801 -0
  334. package/studio/web/assets/fa-solid-900-B4ZZ7kfP.svg +5034 -0
  335. package/studio/web/assets/fa-solid-900-B6Axprfb.eot +0 -0
  336. package/studio/web/assets/fa-solid-900-BUswJgRo.woff2 +0 -0
  337. package/studio/web/assets/fa-solid-900-DOXgCApm.woff +0 -0
  338. package/studio/web/assets/fa-solid-900-mxuxnBEa.ttf +0 -0
  339. package/studio/web/assets/index-BTgXJX9d.js +235 -0
  340. package/studio/web/assets/index-BTgXJX9d.js.map +1 -0
  341. package/studio/web/assets/index-C-GXfcup.js +37 -0
  342. package/studio/web/assets/index-C-GXfcup.js.map +1 -0
  343. package/studio/web/assets/index-PFlNdimM.js +2 -0
  344. package/studio/web/assets/index-PFlNdimM.js.map +1 -0
  345. package/studio/web/assets/index-Y2g_iFpU.css +1 -0
  346. package/studio/web/assets/index-jiPwkrsB.css +1 -0
  347. package/studio/web/assets/index.lazy-C3TJZJ4o.js +266 -0
  348. package/studio/web/assets/index.lazy-C3TJZJ4o.js.map +1 -0
  349. package/studio/web/assets/profiler-DotzgiCJ.js +2 -0
  350. package/studio/web/assets/profiler-DotzgiCJ.js.map +1 -0
  351. package/studio/web/assets/react-redux-VxUEx_mU.js +6 -0
  352. package/studio/web/assets/react-redux-VxUEx_mU.js.map +1 -0
  353. package/studio/web/assets/startRecording-B_9J9Csd.js +3 -0
  354. package/studio/web/assets/startRecording-B_9J9Csd.js.map +1 -0
  355. package/studio/web/fabric-signup-background.webp +0 -0
  356. package/studio/web/fabric-signup-text.png +0 -0
  357. package/studio/web/favicon_purple.png +0 -0
  358. package/studio/web/github-icon.svg +15 -0
  359. package/studio/web/harper-fabric_black.png +0 -0
  360. package/studio/web/harper-fabric_white.png +0 -0
  361. package/studio/web/harper-studio_white.png +0 -0
  362. package/studio/web/index.html +16 -0
  363. package/studio/web/running.css +148 -0
  364. package/studio/web/running.html +147 -0
  365. package/studio/web/running.js +111 -0
  366. package/upgrade/UpgradeObjects.js +13 -0
  367. package/upgrade/directives/directivesController.js +90 -0
  368. package/upgrade/directivesManager.js +139 -0
  369. package/upgrade/upgradePrompt.js +124 -0
  370. package/upgrade/upgradeUtilities.js +28 -0
  371. package/utility/AWS/AWSConnector.js +29 -0
  372. package/utility/OperationFunctionCaller.js +63 -0
  373. package/utility/assignCmdEnvVariables.js +62 -0
  374. package/utility/common_utils.js +867 -0
  375. package/utility/environment/environmentManager.js +208 -0
  376. package/utility/environment/systemInformation.js +355 -0
  377. package/utility/errors/commonErrors.js +267 -0
  378. package/utility/errors/hdbError.js +146 -0
  379. package/utility/functions/date/dateFunctions.js +65 -0
  380. package/utility/functions/geo.js +355 -0
  381. package/utility/functions/sql/alaSQLExtension.js +104 -0
  382. package/utility/globalSchema.js +35 -0
  383. package/utility/hdbTerms.ts +819 -0
  384. package/utility/install/checkJWTTokensExist.js +62 -0
  385. package/utility/install/harperdb.conf +15 -0
  386. package/utility/install/harperdb.service +14 -0
  387. package/utility/install/installer.js +635 -0
  388. package/utility/installation.ts +30 -0
  389. package/utility/lmdb/DBIDefinition.js +20 -0
  390. package/utility/lmdb/DeleteRecordsResponseObject.js +25 -0
  391. package/utility/lmdb/InsertRecordsResponseObject.js +22 -0
  392. package/utility/lmdb/OpenDBIObject.js +31 -0
  393. package/utility/lmdb/OpenEnvironmentObject.js +41 -0
  394. package/utility/lmdb/UpdateRecordsResponseObject.js +25 -0
  395. package/utility/lmdb/UpsertRecordsResponseObject.js +22 -0
  396. package/utility/lmdb/cleanLMDBMap.js +65 -0
  397. package/utility/lmdb/commonUtility.js +119 -0
  398. package/utility/lmdb/deleteUtility.js +128 -0
  399. package/utility/lmdb/environmentUtility.js +477 -0
  400. package/utility/lmdb/searchCursorFunctions.js +187 -0
  401. package/utility/lmdb/searchUtility.js +918 -0
  402. package/utility/lmdb/terms.js +57 -0
  403. package/utility/lmdb/writeUtility.js +407 -0
  404. package/utility/logging/harper_logger.js +876 -0
  405. package/utility/logging/logRotator.js +157 -0
  406. package/utility/logging/logger.ts +24 -0
  407. package/utility/logging/readLog.js +355 -0
  408. package/utility/logging/transactionLog.js +57 -0
  409. package/utility/mount_hdb.js +59 -0
  410. package/utility/npmUtilities.js +102 -0
  411. package/utility/operationPermissions.ts +112 -0
  412. package/utility/operation_authorization.js +836 -0
  413. package/utility/packageUtils.js +55 -0
  414. package/utility/password.ts +99 -0
  415. package/utility/processManagement/processManagement.js +187 -0
  416. package/utility/processManagement/servicesConfig.js +56 -0
  417. package/utility/scripts/restartHdb.js +24 -0
  418. package/utility/scripts/user_data.sh +13 -0
  419. package/utility/signalling.js +36 -0
  420. package/utility/terms/certificates.js +81 -0
  421. package/utility/when.ts +20 -0
  422. package/v1.d.ts +39 -0
  423. package/v1.js +41 -0
  424. package/v2.d.ts +39 -0
  425. package/v2.js +41 -0
  426. package/validation/bulkDeleteValidator.js +24 -0
  427. package/validation/check_permissions.js +19 -0
  428. package/validation/common_validators.js +95 -0
  429. package/validation/configValidator.js +331 -0
  430. package/validation/deleteValidator.js +15 -0
  431. package/validation/fileLoadValidator.js +153 -0
  432. package/validation/insertValidator.js +40 -0
  433. package/validation/installValidator.js +37 -0
  434. package/validation/readLogValidator.js +64 -0
  435. package/validation/role_validation.js +320 -0
  436. package/validation/schemaMetadataValidator.js +42 -0
  437. package/validation/searchValidator.js +166 -0
  438. package/validation/statusValidator.ts +66 -0
  439. package/validation/transactionLogValidator.js +33 -0
  440. package/validation/user_validation.js +55 -0
  441. package/validation/validationWrapper.js +105 -0
  442. package/dist/resources/analytics/profile.d.ts +0 -2
  443. package/dist/resources/analytics/profile.js +0 -144
  444. package/dist/resources/analytics/profile.js.map +0 -1
package/server/http.ts ADDED
@@ -0,0 +1,640 @@
1
+ /**
2
+ * This module represents the HTTP component for Harper, and receives the HTTP options and uses them to configure
3
+ * HTTP servers
4
+ */
5
+ import { Scope } from '../components/Scope.ts';
6
+ import { Socket } from 'node:net';
7
+ import harperLogger from '../utility/logging/harper_logger.js';
8
+ import { parentPort } from 'node:worker_threads';
9
+ import env from '../utility/environment/environmentManager.js';
10
+ import * as terms from '../utility/hdbTerms.ts';
11
+ import { resolvePath } from '../config/configUtils.js';
12
+ import { getTicketKeys } from './threads/manageThreads.js';
13
+ import { createTLSSelector } from '../security/keys.js';
14
+ import { createSecureServer } from 'node:http2';
15
+ import { createServer as createSecureServerHttp1 } from 'node:https';
16
+ import { createServer, IncomingMessage } from 'node:http';
17
+ import { Request } from './serverHelpers/Request.ts';
18
+ import { appendHeader, Headers } from './serverHelpers/Headers.ts';
19
+ import { Blob } from '../resources/blob.ts';
20
+ import { recordAction, recordActionBinary } from '../resources/analytics/write.ts';
21
+ import { Readable } from 'node:stream';
22
+ import { server, type ServerOptions, type HttpOptions } from './Server.ts';
23
+ import { setPortServerMap, SERVERS } from './serverRegistry.ts';
24
+ import { getComponentName } from '../components/componentLoader.ts';
25
+ import { throttle } from './throttle.ts';
26
+ import { WebSocketServer } from 'ws';
27
+
28
+ const { errorToString } = harperLogger;
29
+ server.http = httpServer;
30
+ server.request = onRequest;
31
+ server.ws = onWebSocket;
32
+ server.upgrade = onUpgrade;
33
+ const websocketServers = {};
34
+ const httpServers = {},
35
+ httpChain = {},
36
+ httpResponders = [];
37
+ let httpOptions: HttpOptions = {};
38
+
39
+ export function handleApplication(scope: Scope) {
40
+ httpOptions = scope.options.getAll() as HttpOptions;
41
+ scope.options.on('change', (_key) => {
42
+ // TODO: Check to see if the key is something we can or can't handle
43
+ httpOptions = scope.options.getAll() as HttpOptions;
44
+ });
45
+ }
46
+ export function getHttpOptions() {
47
+ return httpOptions;
48
+ }
49
+
50
+ export function deliverSocket(fdOrSocket, port, data) {
51
+ // Create a socket and deliver it to the HTTP server
52
+ // HTTP server likes to allow half open sockets
53
+ const socket = fdOrSocket?.read
54
+ ? fdOrSocket
55
+ : new Socket({ fd: fdOrSocket, readable: true, writable: true, allowHalfOpen: true });
56
+ // for each socket, deliver the connection to the HTTP server handler/parser
57
+ const server = SERVERS[port];
58
+ if (server.isSecure) {
59
+ socket.startTime = performance.now();
60
+ }
61
+ if (server) {
62
+ if (typeof server === 'function') server(socket);
63
+ else server.emit('connection', socket);
64
+ if (data) socket.emit('data', data);
65
+ } else {
66
+ const retry = (retries) => {
67
+ // in case the server hasn't registered itself yet
68
+ setTimeout(() => {
69
+ const server = SERVERS[port];
70
+ if (server) {
71
+ if (typeof server === 'function') server(socket);
72
+ else server.emit('connection', socket);
73
+ if (data) socket.emit('data', data);
74
+ } else if (retries < 5) retry(retries + 1);
75
+ else {
76
+ harperLogger.error(`Server on port ${port} was not registered`);
77
+ socket.destroy();
78
+ }
79
+ }, 1000);
80
+ };
81
+ retry(1);
82
+ }
83
+ return socket;
84
+ }
85
+
86
+ const requestMap = new Map();
87
+ export function proxyRequest(message) {
88
+ const { port, event, data, requestId } = message;
89
+ let socket;
90
+ socket = requestMap.get(requestId);
91
+ switch (event) {
92
+ case 'connection':
93
+ socket = deliverSocket(undefined, port);
94
+ requestMap.set(requestId, socket);
95
+ socket.write = (data, encoding, callback) => {
96
+ parentPort.postMessage({
97
+ requestId,
98
+ event: 'data',
99
+ data: data.toString('latin1'),
100
+ });
101
+ if (callback) callback();
102
+ return true;
103
+ };
104
+ socket.end = (data, encoding, callback) => {
105
+ parentPort.postMessage({
106
+ requestId,
107
+ event: 'end',
108
+ data: data?.toString('latin1'),
109
+ });
110
+ if (callback) callback();
111
+ return true;
112
+ };
113
+ const originalDestroy = socket.destroy;
114
+ socket.destroy = () => {
115
+ originalDestroy.call(socket);
116
+ parentPort.postMessage({
117
+ requestId,
118
+ event: 'destroy',
119
+ });
120
+ };
121
+ break;
122
+ case 'data':
123
+ if (!socket._readableState.destroyed) socket.emit('data', Buffer.from(data, 'latin1'));
124
+ break;
125
+ case 'drain':
126
+ if (!socket._readableState.destroyed) socket.emit('drain', {});
127
+ break;
128
+ case 'end':
129
+ if (!socket._readableState.destroyed) socket.emit('end', {});
130
+ break;
131
+ case 'error':
132
+ if (!socket._readableState.destroyed) socket.emit('error', {});
133
+ break;
134
+ }
135
+ }
136
+
137
+ export function registerServer(server, port, checkPort = true) {
138
+ if (!port) {
139
+ // if no port is provided, default to custom functions port
140
+ port = env.get(terms.CONFIG_PARAMS.HTTP_PORT);
141
+ }
142
+ const existingServer = SERVERS[port];
143
+ if (existingServer) {
144
+ // if there is an existing server on this port, we create a cascading delegation to try the request with one
145
+ // server and if doesn't handle the request, cascade to next server (until finally we 404)
146
+ const lastServer = existingServer.lastServer || existingServer;
147
+ if (lastServer === server) throw new Error(`Can not register the same server twice for the same port ${port}`);
148
+ if (checkPort && Boolean(lastServer.sessionIdContext) !== Boolean(server.sessionIdContext) && +port)
149
+ throw new Error(`Can not mix secure HTTPS and insecure HTTP on the same port ${port}`);
150
+ lastServer.off('unhandled', defaultNotFound);
151
+ lastServer.on('unhandled', (request, response) => {
152
+ // fastify can't clean up properly, and as soon as we have received a fastify request, must mark our mode
153
+ // as such
154
+ if (server.cantCleanupProperly) existingServer.cantCleanupProperly = true;
155
+ server.emit('request', request, response);
156
+ });
157
+ existingServer.lastServer = server;
158
+ } else {
159
+ SERVERS[port] = server;
160
+ }
161
+ server.on('unhandled', defaultNotFound);
162
+ }
163
+
164
+ function getPorts(options) {
165
+ let ports = [];
166
+ let port = options?.securePort;
167
+ if (port) ports.push({ port, secure: true });
168
+ port = options?.port;
169
+ if (port) ports.push({ port, secure: false });
170
+ if (ports.length === 0) {
171
+ // if no port is provided, default to http port
172
+ ports = [];
173
+ if (env.get(terms.CONFIG_PARAMS.HTTP_PORT) != null)
174
+ ports.push({
175
+ port: env.get(terms.CONFIG_PARAMS.HTTP_PORT),
176
+ secure: env.get(terms.CONFIG_PARAMS.CUSTOMFUNCTIONS_NETWORK_HTTPS),
177
+ });
178
+ if (env.get(terms.CONFIG_PARAMS.HTTP_SECUREPORT) != null)
179
+ ports.push({ port: env.get(terms.CONFIG_PARAMS.HTTP_SECUREPORT), secure: true });
180
+ }
181
+
182
+ if (options?.usageType === 'operations-api' && env.get(terms.CONFIG_PARAMS.OPERATIONSAPI_NETWORK_DOMAINSOCKET)) {
183
+ ports.push({
184
+ port: resolvePath(env.get(terms.CONFIG_PARAMS.OPERATIONSAPI_NETWORK_DOMAINSOCKET)),
185
+ secure: false,
186
+ });
187
+ }
188
+ return ports;
189
+ }
190
+ export function httpServer(listener, options) {
191
+ const servers = [];
192
+
193
+ for (const { port, secure } of getPorts(options)) {
194
+ servers.push(getHTTPServer(port, secure, options));
195
+ if (typeof listener === 'function') {
196
+ httpResponders[options?.runFirst ? 'unshift' : 'push']({ listener, port: options?.port || port });
197
+ } else {
198
+ listener.isSecure = secure;
199
+ registerServer(listener, port, false);
200
+ }
201
+ httpChain[port] = makeCallbackChain(httpResponders, port);
202
+ }
203
+
204
+ return servers;
205
+ }
206
+ function getHTTPServer(port: number, secure: boolean, options: ServerOptions) {
207
+ const { mtls: isMtls, usageType } = options || {};
208
+ const isOperationsServer = usageType === 'operations-api';
209
+ setPortServerMap(port, { protocol_name: secure ? 'HTTPS' : 'HTTP', name: getComponentName() });
210
+ if (!httpServers[port]) {
211
+ // TODO: These should all come from httpOptions or operationsApiOptions
212
+ const serverPrefix = isOperationsServer ? 'operationsApi_network' : 'http';
213
+ const keepAliveTimeout = env.get(serverPrefix + '_keepAliveTimeout');
214
+ const requestTimeout = env.get(serverPrefix + '_timeout');
215
+ const headersTimeout = env.get(serverPrefix + '_headersTimeout');
216
+ const options = {
217
+ keepAliveTimeout,
218
+ headersTimeout,
219
+ requestTimeout,
220
+ // we set this higher (2x times the default in v22, 8x times the default in v20) because it can help with
221
+ // performance
222
+ highWaterMark: 128 * 1024,
223
+ noDelay: true, // don't delay for Nagle's algorithm, it is a relic of the past that slows things down: https://brooker.co.za/blog/2024/05/09/nagle.html
224
+ keepAlive: true,
225
+ keepAliveInitialDelay: 600, // lower the initial delay to 10 minutes, we want to be proactive about closing unused connections
226
+ maxHeaderSize: env.get(terms.CONFIG_PARAMS.HTTP_MAXHEADERSIZE),
227
+ };
228
+ const mtls = env.get(serverPrefix + '_mtls');
229
+ const mtlsRequired = env.get(serverPrefix + '_mtls_required');
230
+ let http2;
231
+
232
+ if (secure) {
233
+ const tlsConfig = env.get('tls');
234
+ // check if we want to enable HTTP/2; operations server doesn't use HTTP/2 because it doesn't allow the
235
+ // ALPNCallback to work with our custom protocol for replication
236
+ http2 = env.get(serverPrefix + '_http2');
237
+ // If we are in secure mode, we use HTTP/2 (createSecureServer from http2), with back-compat support
238
+ // HTTP/1. We do not use HTTP/2 for insecure mode for a few reasons: browsers do not support insecure
239
+ // HTTP/2. We have seen slower performance with HTTP/2, when used for directly benchmarking. We have
240
+ // also seen problems with insecure HTTP/2 clients negotiating properly (Java HttpClient).
241
+ // TODO: Add an option to not accept the root certificates, and only use the CA
242
+ Object.assign(options, {
243
+ allowHTTP1: true,
244
+ rejectUnauthorized: Boolean(mtlsRequired),
245
+ requestCert: Boolean(mtls || isMtls),
246
+ ticketKeys: getTicketKeys(),
247
+ SNICallback: createTLSSelector(usageType ?? 'server', mtls),
248
+ ciphers: tlsConfig.ciphers ?? tlsConfig[0]?.ciphers,
249
+ });
250
+ }
251
+ const requestHandler = async (nodeRequest: IncomingMessage, nodeResponse: any) => {
252
+ const startTime = performance.now();
253
+ let requestId = 0;
254
+ try {
255
+ const request = new Request(nodeRequest, nodeResponse);
256
+ if (isOperationsServer) request.isOperationsServer = true;
257
+ if (httpOptions.logging?.id) request.requestId = requestId = getRequestId();
258
+ // assign a more WHATWG compliant headers object, this is our real standard interface
259
+ let response = await httpChain[port](request);
260
+ if (!response) {
261
+ // this means that the request was completely handled, presumably through the
262
+ // nodeResponse and we are actually just done
263
+ if (request._nodeResponse.statusCode) {
264
+ logRequest(nodeRequest, request._nodeResponse.statusCode, requestId, performance.now() - startTime);
265
+ return;
266
+ }
267
+ response = unhandled(request);
268
+ }
269
+ if (!response.headers?.set) {
270
+ response.headers = new Headers(response.headers);
271
+ }
272
+
273
+ if (response.status === -1) {
274
+ // This means the HDB stack didn't handle the request, and we can then cascade the request
275
+ // to the server-level handler, forming the bridge to the slower legacy fastify framework that expects
276
+ // to interact with a node HTTP server object.
277
+ for (const headerPair of response.headers || []) {
278
+ nodeResponse.setHeader(headerPair[0], headerPair[1]);
279
+ }
280
+ nodeRequest.baseRequest = request;
281
+ nodeResponse.baseResponse = response;
282
+ return httpServers[port].emit('unhandled', nodeRequest, nodeResponse);
283
+ }
284
+ const status = response.status || 200;
285
+ nodeResponse.statusCode = status;
286
+ const endTime = performance.now();
287
+ const executionTime = endTime - startTime;
288
+ let body = response.body;
289
+ let sentBody;
290
+ let deferWriteHead = false;
291
+ if (!response.handlesHeaders) {
292
+ const headers = response.headers || new Headers();
293
+ if (!body) {
294
+ if (request.method !== 'HEAD') {
295
+ headers.set('Content-Length', '0');
296
+ }
297
+ sentBody = true;
298
+ } else if (body.length >= 0) {
299
+ if (typeof body === 'string') headers.set('Content-Length', Buffer.byteLength(body));
300
+ else headers.set('Content-Length', body.length);
301
+ sentBody = true;
302
+ } else if (body instanceof Blob) {
303
+ // if the size is available now, immediately set it
304
+ if (body.size) headers.set('Content-Length', body.size);
305
+ else if (body.on) {
306
+ deferWriteHead = true;
307
+ body.on('size', (size) => {
308
+ // we can also try to set the Content-Length once the header is read and
309
+ // the size available. but if writeHead is called, this will have no effect. So we
310
+ // need to defer writeHead if we are going to set this
311
+ if (!nodeResponse.headersSent) nodeResponse.setHeader('Content-Length', size);
312
+ });
313
+ }
314
+ body = body.stream();
315
+ }
316
+ let serverTiming = `hdb;dur=${executionTime.toFixed(2)}`;
317
+ if (response.wasCacheMiss) {
318
+ serverTiming += ', miss';
319
+ }
320
+ appendHeader(headers, 'Server-Timing', serverTiming, true);
321
+ if (!nodeResponse.headersSent) {
322
+ if (deferWriteHead) {
323
+ // if we are deferring, we need to set the statusCode and headers, let any other headers be set later
324
+ // until the first write
325
+
326
+ if (headers) {
327
+ if (headers[Symbol.iterator]) {
328
+ for (const [name, value] of headers) {
329
+ nodeResponse.setHeader(name, value);
330
+ }
331
+ } else {
332
+ for (const name in headers) {
333
+ nodeResponse.setHeader(name, headers[name]);
334
+ }
335
+ }
336
+ }
337
+ } // else the fast path, if we don't have to defer
338
+ else nodeResponse.writeHead(status, headers && (headers[Symbol.iterator] ? Array.from(headers) : headers));
339
+ }
340
+ if (sentBody) nodeResponse.end(body);
341
+ }
342
+ const handlerPath = request.handlerPath;
343
+ const method = request.method;
344
+ recordAction(
345
+ executionTime,
346
+ 'duration',
347
+ handlerPath,
348
+ method,
349
+ response.wasCacheMiss == undefined ? undefined : response.wasCacheMiss ? 'cache-miss' : 'cache-hit'
350
+ );
351
+ recordActionBinary(status < 400, 'success', handlerPath, method);
352
+ recordActionBinary(1, 'response_' + status, handlerPath, method);
353
+ logRequest(nodeRequest, status, requestId, executionTime);
354
+ if (!sentBody) {
355
+ if (body instanceof ReadableStream) body = Readable.fromWeb(body);
356
+ if (body[Symbol.iterator] || body[Symbol.asyncIterator]) body = Readable.from(body);
357
+
358
+ // if it is a stream, pipe it
359
+ if (body?.pipe) {
360
+ body.pipe(nodeResponse);
361
+ if (body.destroy)
362
+ nodeResponse.on('close', () => {
363
+ body.destroy();
364
+ });
365
+ let bytesSent = 0;
366
+ body.on('data', (data) => {
367
+ bytesSent += data.length;
368
+ });
369
+ body.on('end', () => {
370
+ recordAction(performance.now() - endTime, 'transfer', handlerPath, method);
371
+ recordAction(bytesSent, 'bytes-sent', handlerPath, method);
372
+ });
373
+ }
374
+ // else just send the buffer/string
375
+ else if (body?.then)
376
+ body.then((body) => {
377
+ nodeResponse.end(body);
378
+ }, onError);
379
+ else nodeResponse.end(body);
380
+ }
381
+ } catch (error) {
382
+ onError(error);
383
+ }
384
+ function onError(error) {
385
+ const headers = error.headers;
386
+ const status = error.statusCode || 500;
387
+ try {
388
+ nodeResponse.writeHead(status, headers && (headers[Symbol.iterator] ? Array.from(headers) : headers));
389
+ } catch {} // silently ignore errors writing headers, because they may have been set already
390
+ nodeResponse.end(errorToString(error));
391
+ logRequest(nodeRequest, status, requestId, performance.now() - startTime);
392
+ // a status code is interpreted as an expected error, so just info or warn, otherwise log as error
393
+ if (error.statusCode) {
394
+ if (error.statusCode === 500) harperLogger.warn(error);
395
+ else harperLogger.info(error);
396
+ } else harperLogger.error(error);
397
+ }
398
+ };
399
+ // create a throttled version of the request handler, so we can throttle POST requests
400
+ const throttledRequestHandler = throttle(
401
+ requestHandler,
402
+ (nodeRequest: IncomingMessage, nodeResponse: any) => {
403
+ // if the request queue is taking too long, we want to return an error
404
+ nodeResponse.statusCode = 503;
405
+ nodeResponse.end('Service unavailable, exceeded request queue limit');
406
+ recordAction(true, 'service-unavailable', port);
407
+ },
408
+ env.get(serverPrefix + '_requestQueueLimit')
409
+ );
410
+ const server = (httpServers[port] = (
411
+ secure ? (http2 ? createSecureServer : createSecureServerHttp1) : createServer
412
+ )(options, (nodeRequest: IncomingMessage, nodeResponse: any) => {
413
+ // throttle the requests that can make data modifications because they are more likely to be slow and we don't
414
+ // want to block or slow down other activity
415
+ const method = nodeRequest.method;
416
+ if (method === 'GET' || method === 'OPTIONS' || method === 'HEAD') requestHandler(nodeRequest, nodeResponse);
417
+ else throttledRequestHandler(nodeRequest, nodeResponse);
418
+ }));
419
+
420
+ // Node v16 and earlier required setting this as a property; but carefully, we must only set if it is actually a
421
+ // number or it will actually crash the server
422
+ if (keepAliveTimeout >= 0) server.keepAliveTimeout = keepAliveTimeout;
423
+ if (headersTimeout >= 0) server.headersTimeout = headersTimeout;
424
+
425
+ /* Should we use HTTP2 on upgrade?:
426
+ httpServers[port].on('upgrade', function upgrade(request, socket, head) {
427
+ wss.handleUpgrade(request, socket, head, function done(ws) {
428
+ wss.emit('connection', ws, request);
429
+ });
430
+ });*/
431
+ if (secure) {
432
+ if (!server.ports) server.ports = [];
433
+ server.ports.push(port);
434
+ options.SNICallback.initialize(server);
435
+ if (mtls) server.mtlsConfig = mtls;
436
+ server.on('secureConnection', (socket) => {
437
+ if (socket._parent.startTime) recordAction(performance.now() - socket._parent.startTime, 'tls-handshake', port);
438
+ recordAction(socket.isSessionReused(), 'tls-reused', port);
439
+ });
440
+ server.isSecure = true;
441
+ }
442
+ registerServer(server, port);
443
+ }
444
+ return httpServers[port];
445
+ }
446
+
447
+ function makeCallbackChain(responders, portNum) {
448
+ let nextCallback = unhandled;
449
+ // go through the listeners in reverse order so each callback can be passed to the one before
450
+ // and then each middleware layer can call the next middleware layer
451
+ for (let i = responders.length; i > 0; ) {
452
+ const { listener, port } = responders[--i];
453
+ if (port === portNum || port === 'all') {
454
+ const callback = nextCallback;
455
+ nextCallback = (...args) => {
456
+ // for listener only layers, the response through
457
+ return listener(...args, callback);
458
+ };
459
+ }
460
+ }
461
+ return nextCallback;
462
+ }
463
+ function unhandled(request) {
464
+ if (request.user) {
465
+ // pass on authentication information to the next server
466
+ request._nodeRequest.user = request.user;
467
+ }
468
+ return {
469
+ status: -1,
470
+ body: 'Not found',
471
+ headers: new Headers(),
472
+ };
473
+ }
474
+ function onRequest(listener, options) {
475
+ httpServer(listener, { requestOnly: true, ...options });
476
+ }
477
+ // workaround for inability to defer upgrade from https://github.com/nodejs/node/issues/6339#issuecomment-570511836
478
+ Object.defineProperty(IncomingMessage.prototype, 'upgrade', {
479
+ get() {
480
+ return (
481
+ 'connection' in this.headers &&
482
+ 'upgrade' in this.headers &&
483
+ this.headers.connection.toLowerCase().includes('upgrade') &&
484
+ this.headers.upgrade.toLowerCase() == 'websocket'
485
+ );
486
+ },
487
+ set(_v) {},
488
+ });
489
+
490
+ type OnUpgradeOptions = {
491
+ port?: number;
492
+ securePort?: number;
493
+ runFirst?: boolean;
494
+ };
495
+
496
+ /**
497
+ * @typedef {(request: unknown, next: Listener) => void | Promise<void>} Listener
498
+ */
499
+
500
+ const upgradeListeners = [],
501
+ upgradeChains = {};
502
+
503
+ /**
504
+ *
505
+ * @param {Listener} listener
506
+ * @param {OnUpgradeOptions} options
507
+ * @returns
508
+ */
509
+ function onUpgrade(
510
+ listener: (request: Request, next: (request: Request) => Response) => void,
511
+ options: OnUpgradeOptions
512
+ ) {
513
+ for (const { port } of getPorts(options)) {
514
+ upgradeListeners[options?.runFirst ? 'unshift' : 'push']({ listener, port });
515
+ upgradeChains[port] = makeCallbackChain(upgradeListeners, port);
516
+ }
517
+ }
518
+
519
+ type OnWebSocketOptions = {
520
+ port?: number;
521
+ securePort?: number;
522
+ maxPayload?: number;
523
+ usageType?: string;
524
+ mtls?: boolean;
525
+ };
526
+ const websocketListeners = [],
527
+ websocketChains = {};
528
+ /**
529
+ *
530
+ * @param {Listener} listener
531
+ * @param {OnWebSocketOptions} options
532
+ * @returns
533
+ */
534
+ function onWebSocket(listener: (ws: WebSocket) => void, options: OnWebSocketOptions) {
535
+ const servers = [];
536
+
537
+ for (const { port, secure } of getPorts(options)) {
538
+ setPortServerMap(port, {
539
+ protocol_name: secure ? 'WSS' : 'WS',
540
+ name: getComponentName(),
541
+ });
542
+
543
+ const server = getHTTPServer(port, secure, options);
544
+
545
+ if (!websocketServers[port]) {
546
+ websocketServers[port] = new WebSocketServer({
547
+ noServer: true,
548
+ // TODO: this should be a global config and not per ws listener
549
+ maxPayload: options.maxPayload ?? 100 * 1024 * 1024, // The ws library has a default of 100MB
550
+ });
551
+
552
+ websocketServers[port].on('connection', (ws, incomingMessage) => {
553
+ try {
554
+ const request = new Request(incomingMessage);
555
+ request.isWebSocket = true;
556
+ const chainCompletion = httpChain[port](request);
557
+ harperLogger.debug('Received WS connection, calling listeners', websocketListeners);
558
+ websocketChains[port](ws, request, chainCompletion);
559
+ } catch (error) {
560
+ harperLogger.warn('Error in handling WS connection', error);
561
+ }
562
+ });
563
+
564
+ // Add the default upgrade handler if it doesn't exist.
565
+ onUpgrade(
566
+ (request, socket, head, next) => {
567
+ // If the request has already been upgraded, continue without upgrading
568
+ if (request.__harperdbRequestUpgraded) {
569
+ return next(request, socket, head);
570
+ }
571
+
572
+ // Otherwise, upgrade the socket and then continue
573
+ return websocketServers[port].handleUpgrade(request, socket, head, (ws) => {
574
+ request.__harperdbRequestUpgraded = true;
575
+ next(request, socket, head);
576
+ websocketServers[port].emit('connection', ws, request);
577
+ });
578
+ },
579
+ { port }
580
+ );
581
+
582
+ // Call the upgrade middleware chain
583
+ server.on('upgrade', (request, socket, head) => {
584
+ if (upgradeChains[port]) {
585
+ upgradeChains[port](request, socket, head);
586
+ }
587
+ });
588
+ }
589
+
590
+ servers.push(server);
591
+
592
+ websocketListeners[options?.runFirst ? 'unshift' : 'push']({ listener, port });
593
+ websocketChains[port] = makeCallbackChain(websocketListeners, port);
594
+
595
+ // mqtt doesn't invoke the http handler so this needs to be here to load up the http chains.
596
+ httpChain[port] = makeCallbackChain(httpResponders, port);
597
+ }
598
+
599
+ return servers;
600
+ }
601
+
602
+ function defaultNotFound(request, response) {
603
+ if (response.headersSent || response.writableEnded) return;
604
+ response.writeHead(404);
605
+ response.end('Not found\n');
606
+ logRequest(request, 404, 0, request.requestId);
607
+ }
608
+ let httpLogger: any;
609
+
610
+ export function logRequest(nodeRequest: IncomingMessage, status: number, requestId: number, executionTime?: number) {
611
+ const logging = httpOptions.logging;
612
+ if (logging) {
613
+ if (!httpLogger) {
614
+ httpLogger = harperLogger.forComponent('http');
615
+ }
616
+ const level = status < 400 ? 'info' : status === 500 ? 'error' : 'warn';
617
+ httpLogger[level]?.(
618
+ `${nodeRequest.method} ${nodeRequest.url} ${nodeRequest.socket.encrypted ? 'HTTPS' : 'HTTP'}/${nodeRequest.httpVersion}${
619
+ logging.headers ? ' ' + headersToString(nodeRequest.headers) : ''
620
+ } ${status}${logging.timing && executionTime ? ' ' + executionTime.toFixed(2) + 'ms' : ''}${requestId ? ' id: ' + requestId : ''}`
621
+ );
622
+ }
623
+ }
624
+ function headersToString(headers: any) {
625
+ const result: string[] = [];
626
+ for (const name in headers) {
627
+ result.push(`${name}: ${headers[name]}`);
628
+ }
629
+ return result.join(', ');
630
+ }
631
+ let nextRequestId: BigInt64Array;
632
+ export function getRequestId() {
633
+ if (!nextRequestId) {
634
+ nextRequestId = new BigInt64Array([1n]);
635
+ nextRequestId = new BigInt64Array(
636
+ databases.system.hdb_analytics.primaryStore.getUserSharedBuffer('next-request-id', nextRequestId.buffer)
637
+ );
638
+ }
639
+ return Number(Atomics.add(nextRequestId, 0, 1n));
640
+ }