@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
@@ -0,0 +1,813 @@
1
+ 'use strict';
2
+
3
+ const insert = require('./insert.js');
4
+ const validator = require('../validation/fileLoadValidator.js');
5
+ const needle = require('needle');
6
+ const hdbTerms = require('../utility/hdbTerms.ts');
7
+ const hdbUtils = require('../utility/common_utils.js');
8
+ const { handleHDBError, hdbErrors } = require('../utility/errors/hdbError.js');
9
+ const { HTTP_STATUS_CODES, HDB_ERROR_MSGS, CHECK_LOGS_WRAPPER } = hdbErrors;
10
+ const logger = require('../utility/logging/harper_logger.js');
11
+ const papaParse = require('papaparse');
12
+ hdbUtils.promisifyPapaParse();
13
+ const fs = require('fs-extra');
14
+ const path = require('path');
15
+ const { chain } = require('stream-chain');
16
+ const StreamArray = require('stream-json/streamers/StreamArray');
17
+ const Batch = require('stream-json/utils/Batch');
18
+ const comp = require('stream-chain/utils/comp');
19
+ const { finished } = require('stream');
20
+ const env = require('../utility/environment/environmentManager.js');
21
+ const opFuncCaller = require('../utility/OperationFunctionCaller.js');
22
+ const AWSConnector = require('../utility/AWS/AWSConnector.js');
23
+ const { BulkLoadFileObject, BulkLoadDataObject } = require('./dataObjects/BulkLoadObjects.js');
24
+ const PermissionResponseObject = require('../security/data_objects/PermissionResponseObject.js');
25
+ const { verifyBulkLoadAttributePerms } = require('../utility/operation_authorization.js');
26
+ const { databases } = require('../resources/databases.ts');
27
+ const { coerceType } = require('../resources/Table.ts');
28
+
29
+ const CSV_NO_RECORDS_MSG = 'No records parsed from csv file.';
30
+ const TEMP_DOWNLOAD_DIR = `${env.get('HDB_ROOT')}/tmp`;
31
+ const { schemaRegex } = require('../validation/common_validators.js');
32
+ const HIGHWATERMARK = 1024 * 1024 * 2;
33
+ const MAX_JSON_ARRAY_SIZE = 5000;
34
+
35
+ const ACCEPTABLE_URL_CONTENT_TYPE_ENUM = {
36
+ 'text/csv': true,
37
+ 'application/octet-stream': true,
38
+ 'text/plain': true,
39
+ 'application/vnd.ms-excel': true,
40
+ };
41
+
42
+ module.exports = {
43
+ csvDataLoad,
44
+ csvURLLoad,
45
+ csvFileLoad,
46
+ importFromS3,
47
+ };
48
+
49
+ /**
50
+ * Load csv values specified as a string in the message 'data' field.
51
+ * @param jsonMessage
52
+ * @returns {Promise<string>}
53
+ */
54
+ async function csvDataLoad(jsonMessage) {
55
+ let validationMsg = validator.dataObject(jsonMessage);
56
+ if (validationMsg) {
57
+ throw handleHDBError(
58
+ validationMsg,
59
+ validationMsg.message,
60
+ HTTP_STATUS_CODES.BAD_REQUEST,
61
+ undefined,
62
+ undefined,
63
+ true
64
+ );
65
+ }
66
+
67
+ let bulkLoadResult = {};
68
+ try {
69
+ const mapOfTransforms = createTransformMap(jsonMessage.schema, jsonMessage.table);
70
+ let parseResults = papaParse.parse(jsonMessage.data, {
71
+ header: true,
72
+ skipEmptyLines: true,
73
+ transform: typeFunction.bind(null, mapOfTransforms),
74
+ dynamicTyping: false,
75
+ });
76
+
77
+ const attrsPermsErrors = new PermissionResponseObject();
78
+
79
+ if (
80
+ jsonMessage.hdb_user &&
81
+ jsonMessage.hdb_user?.role &&
82
+ jsonMessage.hdb_user?.role?.permission &&
83
+ jsonMessage.hdb_user?.role?.permission?.super_user !== true
84
+ ) {
85
+ verifyBulkLoadAttributePerms(
86
+ jsonMessage.hdb_user?.role?.permission,
87
+ this.job_operation_function.name,
88
+ jsonMessage.action,
89
+ jsonMessage.schema,
90
+ jsonMessage.table,
91
+ parseResults.meta.fields,
92
+ attrsPermsErrors
93
+ );
94
+ }
95
+
96
+ const attrPermsErrors = attrsPermsErrors.getPermsResponse();
97
+ if (attrPermsErrors) {
98
+ throw handleHDBError(new Error(), attrPermsErrors, HTTP_STATUS_CODES.BAD_REQUEST, undefined, undefined, true);
99
+ }
100
+
101
+ let convertedMsg = new BulkLoadDataObject(
102
+ jsonMessage.action,
103
+ jsonMessage.schema,
104
+ jsonMessage.table,
105
+ parseResults.data
106
+ );
107
+
108
+ bulkLoadResult = await opFuncCaller.callOperationFunctionAsAwait(callBulkFileLoad, convertedMsg, null);
109
+
110
+ if (bulkLoadResult.message === CSV_NO_RECORDS_MSG) {
111
+ return CSV_NO_RECORDS_MSG;
112
+ }
113
+
114
+ return buildResponseMsg(bulkLoadResult.records, bulkLoadResult.number_written);
115
+ } catch (err) {
116
+ throw buildTopLevelErrMsg(err);
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Orchestrates a CSV data load via a file URL. First downloads the file to a temporary folder/file, then calls fileLoad on the
122
+ * downloaded file. Finally deletes temporary file.
123
+ * @param jsonMessage
124
+ * @returns {Promise<string>}
125
+ */
126
+ async function csvURLLoad(jsonMessage) {
127
+ let validationMsg = validator.urlObject(jsonMessage);
128
+ if (validationMsg) {
129
+ throw handleHDBError(
130
+ validationMsg,
131
+ validationMsg.message,
132
+ HTTP_STATUS_CODES.BAD_REQUEST,
133
+ undefined,
134
+ undefined,
135
+ true
136
+ );
137
+ }
138
+
139
+ let csvFileName = `${Date.now()}.csv`;
140
+ const tempFilePath = `${TEMP_DOWNLOAD_DIR}/${csvFileName}`;
141
+
142
+ try {
143
+ await downloadCSVFile(jsonMessage, csvFileName);
144
+ } catch (err) {
145
+ logger.error(HDB_ERROR_MSGS.DOWNLOAD_FILE_ERR(csvFileName) + ' - ' + err);
146
+ throw handleHDBError(err, CHECK_LOGS_WRAPPER(HDB_ERROR_MSGS.DOWNLOAD_FILE_ERR(csvFileName)));
147
+ }
148
+
149
+ try {
150
+ let csvFileLoadObj = new BulkLoadFileObject(
151
+ this.job_operation_function.name,
152
+ jsonMessage.action,
153
+ jsonMessage.schema,
154
+ jsonMessage.table,
155
+ tempFilePath,
156
+ hdbTerms.VALID_S3_FILE_TYPES.CSV,
157
+ jsonMessage.hdb_user?.role?.permission
158
+ );
159
+
160
+ let bulkLoadResult = await fileLoad(csvFileLoadObj);
161
+
162
+ // Remove the downloaded temporary CSV file and directory once fileLoad complete
163
+ await deleteTempFile(tempFilePath);
164
+
165
+ return bulkLoadResult;
166
+ } catch (err) {
167
+ await deleteTempFile(tempFilePath);
168
+ throw buildTopLevelErrMsg(err);
169
+ }
170
+ }
171
+
172
+ /**
173
+ * This is the top-level API method to handle the local csv file load operation.
174
+ *
175
+ * @param jsonMessage
176
+ * @returns {Promise<string>}
177
+ */
178
+ async function csvFileLoad(jsonMessage) {
179
+ let validationMsg = validator.fileObject(jsonMessage);
180
+ if (validationMsg) {
181
+ throw handleHDBError(
182
+ validationMsg,
183
+ validationMsg.message,
184
+ HTTP_STATUS_CODES.BAD_REQUEST,
185
+ undefined,
186
+ undefined,
187
+ true
188
+ );
189
+ }
190
+
191
+ let csvFileLoadObj = new BulkLoadFileObject(
192
+ this.job_operation_function.name,
193
+ jsonMessage.action,
194
+ jsonMessage.schema,
195
+ jsonMessage.table,
196
+ jsonMessage.file_path,
197
+ hdbTerms.VALID_S3_FILE_TYPES.CSV,
198
+ jsonMessage.hdb_user?.role?.permission
199
+ );
200
+
201
+ try {
202
+ return await fileLoad(csvFileLoadObj);
203
+ } catch (err) {
204
+ throw buildTopLevelErrMsg(err);
205
+ }
206
+ }
207
+
208
+ /**
209
+ * This is the top-level API method that handles CSV and JSON file imports from private S3 buckets. First downloads
210
+ * the file to a temporary folder/file, then calls fileLoad on the downloaded file. Finally deletes temporary file.
211
+ *
212
+ * @param jsonMessage
213
+ * @returns {Promise<string>}
214
+ */
215
+ async function importFromS3(jsonMessage) {
216
+ let validationMsg = validator.s3FileObject(jsonMessage);
217
+ if (validationMsg) {
218
+ throw handleHDBError(
219
+ validationMsg,
220
+ validationMsg.message,
221
+ HTTP_STATUS_CODES.BAD_REQUEST,
222
+ undefined,
223
+ undefined,
224
+ true
225
+ );
226
+ }
227
+
228
+ let tempFilePath;
229
+ try {
230
+ let s3FileType = path.extname(jsonMessage.s3.key);
231
+ let s3FileName = `${Date.now()}${s3FileType}`;
232
+ tempFilePath = `${TEMP_DOWNLOAD_DIR}/${s3FileName}`;
233
+
234
+ let s3FileLoadObj = new BulkLoadFileObject(
235
+ this.job_operation_function.name,
236
+ jsonMessage.action,
237
+ jsonMessage.schema,
238
+ jsonMessage.table,
239
+ tempFilePath,
240
+ s3FileType,
241
+ jsonMessage.hdb_user?.role?.permission
242
+ );
243
+
244
+ await downloadFileFromS3(s3FileName, jsonMessage);
245
+
246
+ let bulkLoadResult = await fileLoad(s3FileLoadObj);
247
+
248
+ // Remove the downloaded temporary file once fileLoad complete
249
+ await deleteTempFile(tempFilePath);
250
+
251
+ return bulkLoadResult;
252
+ } catch (err) {
253
+ await deleteTempFile(tempFilePath);
254
+ throw buildTopLevelErrMsg(err);
255
+ }
256
+ }
257
+
258
+ /**
259
+ * Gets a file via URL, then creates a temporary directory in hdb root and writes file to disk.
260
+ * @param req
261
+ * @param csvFileName
262
+ * @returns {Promise<void>}
263
+ */
264
+ async function downloadCSVFile(req, csvFileName) {
265
+ let response;
266
+ try {
267
+ const options = req.passthrough_headers ? { headers: req.passthrough_headers } : undefined;
268
+ response = await needle('get', req.csv_url, options);
269
+ } catch (err) {
270
+ const errMsg = `Error downloading CSV file from ${req.csv_url}, status code: ${err.statusCode}. Check the log for more information.`;
271
+ throw handleHDBError(err, errMsg, err.statusCode, hdbTerms.LOG_LEVELS.ERROR, 'Error downloading CSV file - ' + err);
272
+ }
273
+
274
+ validateURLResponse(response, req.csv_url);
275
+
276
+ await writeFileToTempFolder(csvFileName, response.raw);
277
+ }
278
+
279
+ /**
280
+ * Used to create the read stream from the S3 bucket to pipe into a local write stream.
281
+ * @param s3FileName - file name used to save the downloaded file locally in the tmp file
282
+ * @param jsonMessage
283
+ * @returns {Promise<void>}
284
+ */
285
+ async function downloadFileFromS3(s3FileName, jsonMessage) {
286
+ try {
287
+ const tempDownloadLocation = `${TEMP_DOWNLOAD_DIR}/${s3FileName}`;
288
+ await fs.mkdirp(TEMP_DOWNLOAD_DIR);
289
+ await fs.writeFile(`${TEMP_DOWNLOAD_DIR}/${s3FileName}`, '', { flag: 'a+' });
290
+ let tempFileStream = await fs.createWriteStream(tempDownloadLocation);
291
+ let s3Stream = await AWSConnector.getFileStreamFromS3(jsonMessage);
292
+
293
+ await new Promise((resolve, reject) => {
294
+ s3Stream.on('error', function (err) {
295
+ reject(err);
296
+ });
297
+
298
+ s3Stream
299
+ .pipe(tempFileStream)
300
+ .on('error', function (err) {
301
+ reject(err);
302
+ })
303
+ .on('close', function () {
304
+ logger.info(`${jsonMessage.s3.key} successfully downloaded to ${tempDownloadLocation}`);
305
+ resolve();
306
+ });
307
+ });
308
+ } catch (err) {
309
+ logger.error(HDB_ERROR_MSGS.S3_DOWNLOAD_ERR + ' - ' + err);
310
+ throw handleHDBError(err, CHECK_LOGS_WRAPPER(HDB_ERROR_MSGS.S3_DOWNLOAD_ERR));
311
+ }
312
+ }
313
+
314
+ /**
315
+ * Used to write the CSV data in the body.data from an http request to the local tmp file for processing
316
+ *
317
+ * @param fileName - file name used to save the downloaded file locally in the tmp file
318
+ * @param responseBody - body.data value in response from http request
319
+ * @returns {Promise<void>}
320
+ */
321
+ async function writeFileToTempFolder(fileName, responseBody) {
322
+ try {
323
+ await fs.mkdirp(TEMP_DOWNLOAD_DIR);
324
+ await fs.writeFile(`${TEMP_DOWNLOAD_DIR}/${fileName}`, responseBody);
325
+ } catch (err) {
326
+ logger.error(HDB_ERROR_MSGS.WRITE_TEMP_FILE_ERR);
327
+ throw handleHDBError(err, CHECK_LOGS_WRAPPER(HDB_ERROR_MSGS.DEFAULT_BULK_LOAD_ERR));
328
+ }
329
+ }
330
+
331
+ /**
332
+ * Deletes temp file downloaded to the tmp dir
333
+ *
334
+ * @param filePath
335
+ * @returns {Promise<void>}
336
+ */
337
+ async function deleteTempFile(filePath) {
338
+ if (filePath) {
339
+ try {
340
+ await fs.access(filePath);
341
+ await fs.unlink(filePath);
342
+ } catch {
343
+ logger.warn(`could not delete temp csv file at ${filePath}, file does not exist`);
344
+ }
345
+ }
346
+ }
347
+
348
+ /**
349
+ * Runs multiple validations on response from HTTP client.
350
+ * @param response
351
+ * @param url
352
+ */
353
+ function validateURLResponse(response, url) {
354
+ if (response.statusCode !== hdbErrors.HTTP_STATUS_CODES.OK) {
355
+ throw handleHDBError(
356
+ new Error(),
357
+ `CSV Load failed from URL: ${url}, status code: ${response.statusCode}, message: ${response.statusMessage}`,
358
+ HTTP_STATUS_CODES.BAD_REQUEST
359
+ );
360
+ }
361
+
362
+ if (!ACCEPTABLE_URL_CONTENT_TYPE_ENUM[response.headers['content-type']]) {
363
+ throw handleHDBError(
364
+ new Error(),
365
+ `CSV Load failed from URL: ${url}, unsupported content type: ${response.headers['content-type']}`,
366
+ HTTP_STATUS_CODES.BAD_REQUEST
367
+ );
368
+ }
369
+
370
+ if (!response.raw) {
371
+ throw handleHDBError(
372
+ new Error(),
373
+ `CSV Load failed from URL: ${url}, no csv found at url`,
374
+ HTTP_STATUS_CODES.BAD_REQUEST
375
+ );
376
+ }
377
+ }
378
+
379
+ /**
380
+ * Parse and load CSV or JSON values.
381
+ *
382
+ * @param jsonMessage - An object representing the CSV file.
383
+ * @returns validationMsg - Contains any validation errors found
384
+ * @returns error - any errors found reading the csv file
385
+ * @return err - any errors found during the bulk load
386
+ *
387
+ */
388
+ async function fileLoad(jsonMessage) {
389
+ try {
390
+ let bulkLoadResult;
391
+
392
+ switch (jsonMessage.file_type) {
393
+ case hdbTerms.VALID_S3_FILE_TYPES.CSV:
394
+ bulkLoadResult = await callPapaParse(jsonMessage);
395
+ break;
396
+ case hdbTerms.VALID_S3_FILE_TYPES.JSON:
397
+ bulkLoadResult = await insertJson(jsonMessage);
398
+ break;
399
+ default:
400
+ //we should never get here but here just incase something changes is validation and slips through
401
+ throw handleHDBError(
402
+ new Error(),
403
+ HDB_ERROR_MSGS.DEFAULT_BULK_LOAD_ERR,
404
+ HTTP_STATUS_CODES.BAD_REQUEST,
405
+ hdbTerms.LOG_LEVELS.ERROR,
406
+ HDB_ERROR_MSGS.INVALID_FILE_EXT_ERR(jsonMessage)
407
+ );
408
+ }
409
+
410
+ return buildResponseMsg(bulkLoadResult.records, bulkLoadResult.number_written);
411
+ } catch (err) {
412
+ throw buildTopLevelErrMsg(err);
413
+ }
414
+ }
415
+
416
+ /**
417
+ * Passed to papaparse to validate chunks of csv data from a read stream.
418
+ *
419
+ * @param jsonMessage - An object representing the CSV file.
420
+ * @param reject - A promise object bound to function through hdbUtils.promisifyPapaParse()
421
+ * @param results - An object returned by papaparse containing parsed csv data, errors and meta.
422
+ * @param parser - An object returned by papaparse contains abort, pause and resume.
423
+ * @returns if validation error found returns Promise<error>, if no error nothing is returned.
424
+ */
425
+ async function validateChunk(jsonMessage, permsValidationResp, reject, results, parser) {
426
+ const resultsData = results.data ? results.data : results;
427
+ if (resultsData.length === 0) {
428
+ return;
429
+ }
430
+
431
+ // parser pause and resume prevent the parser from getting ahead of validation.
432
+ if (parser) {
433
+ parser.pause();
434
+ }
435
+ let writeObject = {
436
+ operation: jsonMessage.action,
437
+ schema: jsonMessage.schema,
438
+ table: jsonMessage.table,
439
+ records: resultsData,
440
+ };
441
+
442
+ try {
443
+ const { attributes } = await insert.validation(writeObject);
444
+ if (jsonMessage.role_perms && jsonMessage.role_perms.super_user !== true) {
445
+ verifyBulkLoadAttributePerms(
446
+ jsonMessage.role_perms,
447
+ jsonMessage.op,
448
+ jsonMessage.action,
449
+ jsonMessage.schema,
450
+ jsonMessage.table,
451
+ attributes,
452
+ permsValidationResp
453
+ );
454
+ }
455
+
456
+ if (parser) {
457
+ parser.resume();
458
+ }
459
+ } catch (err) {
460
+ // reject is a promise object bound to chunk function through hdbUtils.promisifyPapaParse(). In the case of an error
461
+ // reject will bubble up to hdbUtils.promisifyPapaParse() and return a reject promise object with given error.
462
+ const errResp = handleHDBError(err);
463
+ reject(errResp);
464
+ }
465
+ }
466
+
467
+ /**
468
+ * Passed to papaparse to insert, update, or upsert chunks of csv data from a read stream.
469
+ *
470
+ * @param jsonMessage - An object representing the CSV file.
471
+ * @param insertResults - An object passed by reference used to accumulate results from insert, update, or upsert function.
472
+ * @param reject - A promise object bound to function through hdbUtils.promisifyPapaParse().
473
+ * @param results - An object returned by papaparse containing parsed csv data, errors and meta.
474
+ * @param parser - An object returned by papaparse contains abort, pause and resume.
475
+ * @returns if validation error found returns Promise<error>, if no error nothing is returned.
476
+ */
477
+ async function insertChunk(jsonMessage, insertResults, reject, results, parser) {
478
+ const resultsData = results.data ? results.data : results;
479
+ if (resultsData.length === 0) {
480
+ return;
481
+ }
482
+ hdbUtils.autoCastJSONDeep(resultsData);
483
+ // parser pause and resume prevent the parser from getting ahead of insert.
484
+ if (parser) {
485
+ parser.pause();
486
+ }
487
+
488
+ let fields = results.meta ? results.meta.fields : null;
489
+
490
+ if (fields) {
491
+ resultsData.forEach((record) => {
492
+ if (!hdbUtils.isEmpty(record) && !hdbUtils.isEmpty(record['__parsed_extra'])) {
493
+ delete record['__parsed_extra'];
494
+ }
495
+ });
496
+ } else {
497
+ const fieldsSet = new Set();
498
+ resultsData.forEach((record) => {
499
+ Object.keys(record).forEach((key) => fieldsSet.add(key));
500
+ });
501
+ fields = [...fieldsSet];
502
+ }
503
+
504
+ try {
505
+ let convertedMsg = {
506
+ schema: jsonMessage.schema,
507
+ table: jsonMessage.table,
508
+ action: jsonMessage.action,
509
+ data: resultsData,
510
+ };
511
+ let bulkLoadChunkResult = await opFuncCaller.callOperationFunctionAsAwait(callBulkFileLoad, convertedMsg, null);
512
+ insertResults.records += bulkLoadChunkResult.records;
513
+ insertResults.number_written += bulkLoadChunkResult.number_written;
514
+ if (parser) {
515
+ parser.resume();
516
+ }
517
+ } catch (err) {
518
+ // reject is a promise object bound to chunk function through hdbUtils.promisifyPapaParse(). In the case of an error
519
+ // reject will bubble up to hdbUtils.promisifyPapaParse() and return a reject promise object with given error.
520
+ const errResp = handleHDBError(
521
+ err,
522
+ CHECK_LOGS_WRAPPER(HDB_ERROR_MSGS.INSERT_CSV_ERR),
523
+ HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR,
524
+ hdbTerms.LOG_LEVELS.ERROR,
525
+ HDB_ERROR_MSGS.INSERT_CSV_ERR + ' - ' + err
526
+ );
527
+ reject(errResp);
528
+ }
529
+ }
530
+
531
+ /**
532
+ * Handles two asynchronous calls to csv parser papaparse.
533
+ * First call validates the full read stream from csv file by calling papaparse with validateChunk function. The entire
534
+ * stream is consumed by validate because all rows must be validated before calling insert.
535
+ * Second call inserts a new csv file read stream by calling papaparse with insertChunk function.
536
+ *
537
+ * @param jsonMessage - An object representing the CSV file.
538
+ * @returns {Promise<{records: number, number_written: number}>}
539
+ */
540
+ async function callPapaParse(jsonMessage) {
541
+ // passing insertResults object by reference to insertChunk function where it accumulate values from bulk load results.
542
+ let insertResults = {
543
+ records: 0,
544
+ number_written: 0,
545
+ };
546
+ const mapOfTransforms = createTransformMap(jsonMessage.schema, jsonMessage.table);
547
+ try {
548
+ const attrsPermsErrors = new PermissionResponseObject();
549
+ let stream = fs.createReadStream(jsonMessage.file_path, { highWaterMark: HIGHWATERMARK });
550
+ stream.setEncoding('utf8');
551
+
552
+ await papaParse.parsePromise(
553
+ stream,
554
+ validateChunk.bind(null, jsonMessage, attrsPermsErrors),
555
+ typeFunction.bind(null, mapOfTransforms)
556
+ );
557
+
558
+ const attrPermsErrors = attrsPermsErrors.getPermsResponse();
559
+ if (attrPermsErrors) {
560
+ throw handleHDBError(new Error(), attrPermsErrors, HTTP_STATUS_CODES.BAD_REQUEST);
561
+ }
562
+
563
+ stream = fs.createReadStream(jsonMessage.file_path, { highWaterMark: HIGHWATERMARK });
564
+ stream.setEncoding('utf8');
565
+
566
+ await papaParse.parsePromise(
567
+ stream,
568
+ insertChunk.bind(null, jsonMessage, insertResults),
569
+ typeFunction.bind(null, mapOfTransforms)
570
+ );
571
+ stream.destroy();
572
+
573
+ return insertResults;
574
+ } catch (err) {
575
+ throw handleHDBError(
576
+ err,
577
+ CHECK_LOGS_WRAPPER(HDB_ERROR_MSGS.PAPA_PARSE_ERR),
578
+ HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR,
579
+ hdbTerms.LOG_LEVELS.ERROR,
580
+ HDB_ERROR_MSGS.PAPA_PARSE_ERR + err
581
+ );
582
+ }
583
+ }
584
+
585
+ function createTransformMap(schema, table) {
586
+ const attributes = databases[schema][table].attributes;
587
+ let mapOfTransforms = new Map(); // I don't know if this should be a Map, but this just makes a map of attributes with type coercions that we want
588
+ for (let attribute of attributes) {
589
+ if (attribute.type && !attribute.computed && !attribute.relationship)
590
+ mapOfTransforms.set(attribute.name, (value) => coerceType(value, attribute)); // here is
591
+ // the transform to use
592
+ }
593
+ return mapOfTransforms;
594
+ }
595
+
596
+ function typeFunction(mapOfTransforms, value, header) {
597
+ let transform = mapOfTransforms.get(header);
598
+ if (transform) return transform(value);
599
+ return hdbUtils.autoCast(value);
600
+ }
601
+
602
+ async function insertJson(jsonMessage) {
603
+ // passing insertResults object by reference to insertChunk function where it accumulate values from bulk load results.
604
+ let insertResults = {
605
+ records: 0,
606
+ number_written: 0,
607
+ };
608
+
609
+ const throwErr = (e) => {
610
+ throw e;
611
+ };
612
+
613
+ try {
614
+ const attrsPermsErrors = new PermissionResponseObject();
615
+ let jsonStreamer = chain([
616
+ fs.createReadStream(jsonMessage.file_path, { encoding: 'utf-8' }),
617
+ StreamArray.withParser(),
618
+ (data) => data.value,
619
+ new Batch({ batchSize: MAX_JSON_ARRAY_SIZE }),
620
+ comp(async (chunk) => {
621
+ await validateChunk(jsonMessage, attrsPermsErrors, throwErr, chunk);
622
+ }),
623
+ ]);
624
+
625
+ await new Promise((resolve, reject) => {
626
+ finished(jsonStreamer, (err) => {
627
+ if (err) {
628
+ reject(err);
629
+ } else {
630
+ resolve();
631
+ }
632
+ });
633
+ jsonStreamer.resume();
634
+ });
635
+
636
+ const attrPermsErrors = attrsPermsErrors.getPermsResponse();
637
+ if (attrPermsErrors) {
638
+ throw handleHDBError(new Error(), attrPermsErrors, HTTP_STATUS_CODES.BAD_REQUEST);
639
+ }
640
+
641
+ let jsonStreamerInsert = chain([
642
+ fs.createReadStream(jsonMessage.file_path, { encoding: 'utf-8' }),
643
+ StreamArray.withParser(),
644
+ (data) => data.value,
645
+ new Batch({ batchSize: MAX_JSON_ARRAY_SIZE }),
646
+ comp(async (chunk) => {
647
+ await insertChunk(jsonMessage, insertResults, throwErr, chunk);
648
+ }),
649
+ ]);
650
+
651
+ await new Promise((resolve, reject) => {
652
+ finished(jsonStreamerInsert, (err) => {
653
+ if (err) {
654
+ reject(err);
655
+ } else {
656
+ resolve();
657
+ }
658
+ });
659
+ jsonStreamerInsert.resume();
660
+ });
661
+
662
+ return insertResults;
663
+ } catch (err) {
664
+ throw handleHDBError(
665
+ err,
666
+ CHECK_LOGS_WRAPPER(HDB_ERROR_MSGS.INSERT_JSON_ERR),
667
+ HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR,
668
+ hdbTerms.LOG_LEVELS.ERROR,
669
+ HDB_ERROR_MSGS.INSERT_JSON_ERR + err
670
+ );
671
+ }
672
+ }
673
+
674
+ async function callBulkFileLoad(jsonMsg) {
675
+ let bulkLoadResult = {};
676
+ try {
677
+ if (jsonMsg.data && jsonMsg.data.length > 0 && validateColumnNames(jsonMsg.data[0])) {
678
+ bulkLoadResult = await bulkFileLoad(jsonMsg.data, jsonMsg.schema, jsonMsg.table, jsonMsg.action);
679
+ } else {
680
+ bulkLoadResult.message = 'No records parsed from csv file.';
681
+ logger.info(bulkLoadResult.message);
682
+ }
683
+ } catch (err) {
684
+ throw buildTopLevelErrMsg(err);
685
+ }
686
+ return bulkLoadResult;
687
+ }
688
+
689
+ /**
690
+ * Validate all attribute names about to be created are valid. Returns true if valid, throws an exception
691
+ * if not.
692
+ * @param createdRecord - A single instance of a record created during csv load.
693
+ * @returns {boolean} - True if valid, throws exception if not.
694
+ */
695
+ function validateColumnNames(createdRecord) {
696
+ let columnNames = Object.keys(createdRecord);
697
+ for (let key of columnNames) {
698
+ if (!schemaRegex.test(key)) {
699
+ throw new Error(`Invalid column name '${key}', cancelling load operation`);
700
+ }
701
+ }
702
+ return true;
703
+ }
704
+
705
+ /**
706
+ * Performs a bulk insert, update, or upsert depending on the action passed to the function.
707
+ * @param records - The records to be inserted/updated/upserted
708
+ * @param schema - The schema containing the specified table
709
+ * @param table - The table to perform the insert/update/upsert
710
+ * @param action - Specify insert/update/upsert the specified records
711
+ * @returns {Promise<{records: *, new_attributes: *, number_written: number}>}
712
+ */
713
+ async function bulkFileLoad(records, schema, table, action) {
714
+ if (!action) {
715
+ action = 'insert';
716
+ }
717
+
718
+ let targetObject = {
719
+ operation: action,
720
+ schema,
721
+ table,
722
+ records,
723
+ };
724
+
725
+ let writeFunction;
726
+ switch (action) {
727
+ case 'insert':
728
+ writeFunction = insert.insert;
729
+ break;
730
+ case 'update':
731
+ writeFunction = insert.update;
732
+ break;
733
+ case 'upsert':
734
+ writeFunction = insert.upsert;
735
+ break;
736
+ default:
737
+ throw handleHDBError(
738
+ new Error(),
739
+ HDB_ERROR_MSGS.INVALID_ACTION_PARAM_ERR(action),
740
+ HTTP_STATUS_CODES.BAD_REQUEST,
741
+ hdbTerms.LOG_LEVELS.ERROR,
742
+ HDB_ERROR_MSGS.INVALID_ACTION_PARAM_ERR(action)
743
+ );
744
+ }
745
+
746
+ try {
747
+ let writeResponse = await writeFunction(targetObject);
748
+
749
+ let modifiedHashes;
750
+ switch (action) {
751
+ case 'insert':
752
+ modifiedHashes = writeResponse.inserted_hashes;
753
+ break;
754
+ case 'update':
755
+ modifiedHashes = writeResponse.update_hashes;
756
+ break;
757
+ case 'upsert':
758
+ modifiedHashes = writeResponse.upserted_hashes;
759
+ break;
760
+ default:
761
+ //We should never get here based on the error thrown in the switch above
762
+ break;
763
+ }
764
+
765
+ if (Array.isArray(writeResponse.skipped_hashes) && writeResponse.skipped_hashes.length > 0) {
766
+ let tableInfo = global.hdb_schema[schema][table];
767
+ let hash_attribute = tableInfo.hash_attribute;
768
+
769
+ let x = records.length;
770
+ while (x--) {
771
+ if (writeResponse.skipped_hashes.indexOf(records[x][hash_attribute]) >= 0) {
772
+ records.splice(x, 1);
773
+ }
774
+ }
775
+ }
776
+
777
+ let number_written = hdbUtils.isEmptyOrZeroLength(modifiedHashes) ? 0 : modifiedHashes.length;
778
+ return {
779
+ records: records.length,
780
+ number_written,
781
+ new_attributes: writeResponse.new_attributes,
782
+ };
783
+ } catch (err) {
784
+ throw buildTopLevelErrMsg(err);
785
+ }
786
+ }
787
+
788
+ /**
789
+ * Builds the response message returned by bulk load operations.
790
+ * @param totalRecords
791
+ * @param number_written
792
+ */
793
+ function buildResponseMsg(totalRecords, number_written) {
794
+ return `successfully loaded ${number_written} of ${totalRecords} records`;
795
+ }
796
+
797
+ /**
798
+ * Uses handleHDBError here to ensure the specific error that has already been created when thrown lower down
799
+ * the stack is used OR, if it hasn't been handled yet, will create and return the generic error message for bulk load
800
+ * and log the error
801
+ *
802
+ * @param err - error caught to be turned into a HDBError (if not already) or passed through via HDBError
803
+ * @returns {HdbError}
804
+ */
805
+ function buildTopLevelErrMsg(err) {
806
+ return handleHDBError(
807
+ err,
808
+ CHECK_LOGS_WRAPPER(HDB_ERROR_MSGS.DEFAULT_BULK_LOAD_ERR),
809
+ HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR,
810
+ hdbTerms.LOG_LEVELS.ERROR,
811
+ HDB_ERROR_MSGS.DEFAULT_BULK_LOAD_ERR + ' - ' + err
812
+ );
813
+ }