@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,789 @@
1
+ import type { User } from '../security/user.ts';
2
+ import type { RecordObject } from './RecordEncoder.js';
3
+ import {
4
+ ResourceInterface,
5
+ SubscriptionRequest,
6
+ Id,
7
+ Context,
8
+ Query,
9
+ SourceContext,
10
+ RequestTargetOrId,
11
+ } from './ResourceInterface.ts';
12
+ import { randomUUID } from 'crypto';
13
+ import { DatabaseTransaction, type Transaction } from './DatabaseTransaction.ts';
14
+ import { IterableEventQueue } from './IterableEventQueue.ts';
15
+ import { _assignPackageExport } from '../globals.js';
16
+ import { ClientError, AccessViolation } from '../utility/errors/hdbError.js';
17
+ import { transaction, contextStorage } from './transaction.ts';
18
+ import { parseQuery } from './search.ts';
19
+ import { RequestTarget } from './RequestTarget.ts';
20
+ import { when, promiseNormalize } from '../utility/when.ts';
21
+
22
+ const EXTENSION_TYPES = {
23
+ json: 'application/json',
24
+ cbor: 'application/cbor',
25
+ msgpack: 'application/x-msgpack',
26
+ csv: 'text/csv',
27
+ };
28
+
29
+ /**
30
+ * This is the main class that can be extended for any resource in Harper and provides the essential reusable
31
+ * uniform interface for interacting with data, defining the API for providing data (data sources) and for consuming
32
+ * data. This interface is used pervasively in Harper and is implemented by database tables and can be used to define
33
+ * sources for caching, real-data sources for messaging protocols, and RESTful endpoints, as well as any other types of
34
+ * data aggregation, processing, or monitoring.
35
+ *
36
+ * This base Resource class provides a set of static methods that are main entry points for querying and updating data
37
+ * in resources/tables. The static methods provide the default handling of arguments, context, and ensuring that
38
+ * internal actions are wrapped in a transaction. The base Resource class intended to be extended, and the instance
39
+ * methods can be overridden to provide specific implementations of actions like get, put, post, delete, and subscribe.
40
+ */
41
+ export class Resource<Record extends object = any> implements ResourceInterface<Record> {
42
+ readonly #id: Id;
43
+ readonly #context: Context | SourceContext;
44
+ #isCollection: boolean;
45
+ static transactions: Transaction[] & { timestamp: number };
46
+ static directURLMapping = false;
47
+ static loadAsInstance: boolean;
48
+ constructor(identifier: Id, source: any) {
49
+ this.#id = identifier;
50
+ const context = source?.getContext ? (source.getContext() ?? null) : undefined;
51
+ this.#context = context !== undefined ? context : source || null;
52
+ }
53
+
54
+ /**
55
+ * The get methods are for directly getting a resource, and called for HTTP GET requests.
56
+ */
57
+ static get = transactional(
58
+ function (resource: Resource, query: RequestTarget, _request: Context, _data: any) {
59
+ const result = resource.get?.(query);
60
+ // for the new API we always apply select in the instance method
61
+ if (!resource.constructor.loadAsInstance) return result;
62
+ if (result?.then) return result.then(handleSelect);
63
+ return handleSelect(result);
64
+ function handleSelect(result) {
65
+ let select;
66
+ if ((select = query?.select) && result != null && !result.selectApplied) {
67
+ const transform = transformForSelect(select, resource.constructor);
68
+ if (typeof result?.map === 'function') {
69
+ return result.map(transform);
70
+ } else {
71
+ return transform(result);
72
+ }
73
+ }
74
+ return result;
75
+ }
76
+ },
77
+ {
78
+ type: 'read',
79
+ // allows context to reset/remove transaction after completion so it can be used in immediate mode:
80
+ letItLinger: true,
81
+ ensureLoaded: true, // load from source by default
82
+ hasContent: false,
83
+ async: true, // use async by default
84
+ method: 'get',
85
+ }
86
+ );
87
+
88
+ /**
89
+ * Store the provided record by the provided id. If no id is provided, it is auto-generated.
90
+ */
91
+ static put = transactional(
92
+ function (resource: Resource, query: RequestTarget, request: Context, data: any) {
93
+ if (Array.isArray(data) && resource.#isCollection && resource.constructor.loadAsInstance !== false) {
94
+ const results = [];
95
+ for (const element of data) {
96
+ const resourceClass = resource.constructor;
97
+ const id = element[resourceClass.primaryKey];
98
+ let target = new RequestTarget();
99
+ target.id = id;
100
+ const elementResource = resourceClass.getResource(target, request, {
101
+ async: true,
102
+ });
103
+ if (elementResource.then) results.push(elementResource.then((resource) => resource.put(element, request)));
104
+ else results.push(elementResource.put(element, query));
105
+ }
106
+ return Promise.all(results);
107
+ }
108
+ return resource.put
109
+ ? resource.constructor.loadAsInstance === false
110
+ ? resource.put(query, data)
111
+ : resource.put(data, query)
112
+ : missingMethod(resource, 'put');
113
+ },
114
+ { hasContent: true, type: 'update', method: 'put' }
115
+ );
116
+
117
+ static patch = transactional(
118
+ function (resource: Resource, query: RequestTarget, _request: Context, data: any) {
119
+ // TODO: Allow array like put?
120
+ return resource.patch
121
+ ? resource.constructor.loadAsInstance === false
122
+ ? resource.patch(query, data)
123
+ : resource.patch(data, query)
124
+ : missingMethod(resource, 'patch');
125
+ },
126
+ { hasContent: true, type: 'update', method: 'patch' }
127
+ );
128
+
129
+ static delete = transactional(
130
+ function (resource: Resource, query: RequestTarget, _request: Context, _data: any) {
131
+ return resource.delete ? resource.delete(query) : missingMethod(resource, 'delete');
132
+ },
133
+ { hasContent: false, type: 'delete', method: 'delete' }
134
+ );
135
+
136
+ /**
137
+ * Generate a new primary key for a resource; by default we use UUIDs (for now).
138
+ */
139
+ static getNewId() {
140
+ return randomUUID();
141
+ }
142
+
143
+ /**
144
+ * Create a new resource with the provided record and id. If no id is provided, it is auto-generated. Note that this
145
+ * facilitates creating a new resource, but does not guarantee that this is not overwriting an existing entry.
146
+ * @param idPrefix
147
+ * @param record
148
+ * @param context
149
+ */
150
+ static create(idPrefix: Id, record: any, context: Context): Promise<Id>;
151
+ static create(record: any, context: Context): Promise<Id>;
152
+ static create(idPrefix: any, record: any, context?: Context): Promise<Id> {
153
+ let id: Id;
154
+ if (this.loadAsInstance === false) {
155
+ if (typeof idPrefix === 'object' && idPrefix && !context) {
156
+ // two argument form (record, context), shift the arguments
157
+ context = record;
158
+ record = idPrefix;
159
+ id = new RequestTarget();
160
+ id.isCollection = true;
161
+ } else id = idPrefix;
162
+ } else {
163
+ if (idPrefix == null) id = record?.[this.primaryKey] ?? this.getNewId();
164
+ else if (Array.isArray(idPrefix) && typeof idPrefix[0] !== 'object')
165
+ id = record?.[this.primaryKey] ?? [...idPrefix, this.getNewId()];
166
+ else if (typeof idPrefix !== 'object') id = record?.[this.primaryKey] ?? [idPrefix, this.getNewId()];
167
+ else {
168
+ // two argument form, shift the arguments
169
+ id = idPrefix?.[this.primaryKey] ?? this.getNewId();
170
+ context = record || {};
171
+ record = idPrefix;
172
+ }
173
+ }
174
+ if (context) {
175
+ if (context.getContext) context = context.getContext();
176
+ } else {
177
+ // try to get the context from the async context if possible
178
+ context = contextStorage.getStore() ?? {};
179
+ }
180
+ return transaction(context, async () => {
181
+ context.transaction.startedFrom ??= {
182
+ resourceName: this.name,
183
+ method: 'create',
184
+ };
185
+ const resource = new this(id, context);
186
+ const results = resource.create ? await resource.create(id, record) : missingMethod(resource, 'create');
187
+ context.newLocation = id ?? results?.[this.primaryKey];
188
+ context.createdResource = true;
189
+ return this.loadAsInstance === false ? results : resource;
190
+ });
191
+ }
192
+ static invalidate = transactional(
193
+ function (resource: Resource, query: RequestTarget, _request: Context, _data: any) {
194
+ return resource.invalidate ? resource.invalidate(query) : missingMethod(resource, 'invalidate');
195
+ },
196
+ { hasContent: false, type: 'update', method: 'invalidate' }
197
+ );
198
+
199
+ static post = transactional(
200
+ function (resource: Resource, query: RequestTarget, _request: Context, data: any) {
201
+ if (resource.#id != null) resource.update?.(); // save any changes made during post
202
+ return resource.constructor.loadAsInstance === false ? resource.post(query, data) : resource.post(data, query);
203
+ },
204
+ { hasContent: true, type: 'create', method: 'post' }
205
+ );
206
+
207
+ static update = transactional(
208
+ function (resource: Resource, query: RequestTarget, _request: Context, data: any) {
209
+ return resource.update(query, data);
210
+ },
211
+ { type: 'update', method: 'update' }
212
+ );
213
+
214
+ static connect = transactional(
215
+ function (resource: Resource, query: RequestTarget, _request: Context, data: any) {
216
+ return resource.connect
217
+ ? resource.constructor.loadAsInstance === false
218
+ ? resource.connect(query, data)
219
+ : resource.connect(data, query)
220
+ : missingMethod(resource, 'connect');
221
+ },
222
+ { hasContent: true, type: 'read', method: 'connect' }
223
+ );
224
+
225
+ static subscribe = transactional(
226
+ function (resource: Resource, query: RequestTarget, _request: Context, _data: any) {
227
+ return resource.subscribe ? resource.subscribe(query) : missingMethod(resource, 'subscribe');
228
+ },
229
+ { type: 'read', method: 'subscribe', syncAllowed: true }
230
+ );
231
+
232
+ static publish = transactional(
233
+ function (resource: Resource, query: Map, _request: Context, data: any) {
234
+ if (resource.#id != null) resource.update?.(); // save any changes made during publish
235
+ return resource.publish
236
+ ? resource.constructor.loadAsInstance === false
237
+ ? resource.publish(query, data)
238
+ : resource.publish(data, query)
239
+ : missingMethod(resource, 'publish');
240
+ },
241
+ { hasContent: true, type: 'create', method: 'publish' }
242
+ );
243
+
244
+ static search = transactional(
245
+ function (resource: Resource, query: Query, request: Context) {
246
+ const result = resource.search ? resource.search(query) : missingMethod(resource, 'search');
247
+ const select = request.select;
248
+ if (select && request.hasOwnProperty('select') && result != null && !result.selectApplied) {
249
+ const transform = transformForSelect(select, resource.constructor);
250
+ return result.map(transform);
251
+ }
252
+ return result;
253
+ },
254
+ { type: 'read', method: 'search', hasContent: false, syncAllowed: true }
255
+ );
256
+
257
+ static query = transactional(
258
+ function (resource: Resource, query: Map, _request: Context, data: any) {
259
+ return resource.search
260
+ ? resource.constructor.loadAsInstance === false
261
+ ? resource.search(query, data)
262
+ : resource.search(data, query)
263
+ : missingMethod(resource, 'search');
264
+ },
265
+ { hasContent: true, type: 'read', method: 'query' }
266
+ );
267
+
268
+ static copy = transactional(
269
+ function (resource: Resource, query: Map, _request: Context, data: any) {
270
+ return resource.copy
271
+ ? resource.constructor.loadAsInstance === false
272
+ ? resource.copy(query, data)
273
+ : resource.copy(data, query)
274
+ : missingMethod(resource, 'copy');
275
+ },
276
+ { hasContent: true, type: 'create', method: 'copy' }
277
+ );
278
+
279
+ static move = transactional(
280
+ function (resource: Resource, query: Map, _request: Context, data: any) {
281
+ return resource.move
282
+ ? resource.constructor.loadAsInstance === false
283
+ ? resource.move(query, data)
284
+ : resource.move(data, query)
285
+ : missingMethod(resource, 'move');
286
+ },
287
+ { hasContent: true, type: 'delete', method: 'move' }
288
+ );
289
+
290
+ async post(
291
+ target: RequestTargetOrId,
292
+ newRecord: Partial<Record & RecordObject>
293
+ ): Promise<Record & Partial<RecordObject>> {
294
+ if (this.constructor.loadAsInstance === false) {
295
+ if (target.isCollection && this.create) {
296
+ newRecord = await this.create(target, newRecord);
297
+ return newRecord?.[this.constructor.primaryKey];
298
+ }
299
+ } else {
300
+ if (this.#isCollection) {
301
+ const resource = await this.constructor.create(this.#id, target, this.#context);
302
+ return resource.#id;
303
+ }
304
+ }
305
+ missingMethod(this, 'post');
306
+ }
307
+
308
+ static isCollection(resource) {
309
+ return resource && resource.#isCollection;
310
+ }
311
+ get isCollection() {
312
+ return this.#isCollection;
313
+ }
314
+ static coerceId(id: string): number | string {
315
+ return id;
316
+ }
317
+ static parseQuery(search, query) {
318
+ return parseQuery(search, query);
319
+ }
320
+ static parsePath(path, context, query) {
321
+ const dotIndex = path.indexOf('.');
322
+ if (dotIndex > -1) {
323
+ // handle paths of the form /path/id.property
324
+ const property = path.slice(dotIndex + 1);
325
+ const requestedContentType = context?.headers && EXTENSION_TYPES[property];
326
+ if (requestedContentType) {
327
+ // handle path.json, path.cbor, etc. for requesting a specific content type using just the URL
328
+ context.requestedContentType = requestedContentType;
329
+ path = path.slice(0, dotIndex); // remove the property from the path
330
+ } else if (this.attributes?.find((attribute) => attribute.name === property)) {
331
+ // handle path.attribute for requesting a specific attribute using just the URL
332
+ path = path.slice(0, dotIndex); // remove the property from the path
333
+ if (query) query.property = property;
334
+ else {
335
+ return {
336
+ property,
337
+ id: path,
338
+ };
339
+ }
340
+ }
341
+ }
342
+ return path;
343
+ }
344
+ /**
345
+ * Gets an instance of a resource by id
346
+ * @param id
347
+ * @param request
348
+ * @param options
349
+ * @returns
350
+ */
351
+ static getResource(
352
+ target: RequestTarget,
353
+ request: Context | SourceContext,
354
+ options?: any
355
+ ): Resource | Promise<Resource> {
356
+ let resource;
357
+ const id = target.id;
358
+ let context = request.getContext?.();
359
+ let isCollection;
360
+ if (typeof request.isCollection === 'boolean' && request.hasOwnProperty('isCollection'))
361
+ isCollection = request.isCollection;
362
+ else isCollection = options?.isCollection;
363
+ // if it is a collection and we have a collection class defined, use it
364
+ const constructor = (isCollection && this.Collection) || this;
365
+ if (!context) context = context === undefined ? request : {};
366
+ resource = new constructor(id, context); // outside of a transaction, just create an instance
367
+ if (isCollection) resource.#isCollection = true;
368
+ return resource;
369
+ }
370
+
371
+ /**
372
+ * This is called by protocols that wish to make a subscription for real-time notification/updates.
373
+ * This default implementation simply provides a streaming iterator that does not deliver any notifications
374
+ * but implementors can call send with
375
+ */
376
+ // eslint-disable-next-line no-unused-vars
377
+ subscribe(request: SubscriptionRequest): AsyncIterable<Record> {
378
+ return new IterableEventQueue();
379
+ }
380
+
381
+ connect(target: RequestTarget, incomingMessages: IterableEventQueue<Record>): AsyncIterable<Record> {
382
+ // convert subscription to an (async) iterator
383
+ const query = this.constructor.loadAsInstance === false ? target : incomingMessages;
384
+ if (query?.subscribe !== false) {
385
+ // subscribing is the default action, but can be turned off
386
+ return this.subscribe?.(query);
387
+ }
388
+ return new IterableEventQueue();
389
+ }
390
+
391
+ // Default permissions (super user only accesss):
392
+ // eslint-disable-next-line no-unused-vars
393
+ allowRead(user: User, target: RequestTarget, context: Context): boolean | Promise<boolean> {
394
+ return user?.role.permission.super_user;
395
+ }
396
+ // eslint-disable-next-line no-unused-vars
397
+ allowUpdate(user: User, record: Promise<Record & RecordObject>, context: Context): boolean | Promise<boolean> {
398
+ return user?.role.permission.super_user;
399
+ }
400
+ // eslint-disable-next-line no-unused-vars
401
+ allowCreate(user: User, record: Promise<Record & RecordObject>, context: Context): boolean | Promise<boolean> {
402
+ return user?.role.permission.super_user;
403
+ }
404
+ // eslint-disable-next-line no-unused-vars
405
+ allowDelete(user: User, target: RequestTarget, context: Context): boolean | Promise<boolean> {
406
+ return user?.role.permission.super_user;
407
+ }
408
+ /**
409
+ * Get the primary key value for this resource.
410
+ * @returns primary key
411
+ */
412
+ getId() {
413
+ return this.#id;
414
+ }
415
+ /**
416
+ * Get the context for this resource
417
+ * @returns context object with information about the current transaction, user, and more
418
+ */
419
+ getContext(): Context | SourceContext {
420
+ return this.#context;
421
+ }
422
+
423
+ /**
424
+ * Get the current user for the current request, based on the context.
425
+ * @returns user object or undefined if no user is logged in
426
+ */
427
+ getCurrentUser(): User | undefined {
428
+ return (this.getContext() as Context)?.user;
429
+ }
430
+
431
+ get?(
432
+ target?: RequestTargetOrId
433
+ ):
434
+ | (Record & Partial<RecordObject>)
435
+ | Promise<Record & Partial<RecordObject>>
436
+ | AsyncIterable<Record & Partial<RecordObject>>
437
+ | Promise<AsyncIterable<Record & Partial<RecordObject>>>;
438
+
439
+ search?(target: RequestTargetOrId): AsyncIterable<Record & Partial<RecordObject>>;
440
+
441
+ create?(
442
+ newRecord: Partial<Record & RecordObject>,
443
+ target: RequestTargetOrId
444
+ ): Promise<Record & Partial<RecordObject>>;
445
+ put?(
446
+ record: Record & RecordObject,
447
+ target: RequestTargetOrId
448
+ ): void | (Record & Partial<RecordObject>) | Promise<void | (Record & Partial<RecordObject>)>;
449
+ patch?(
450
+ record: Partial<Record & RecordObject>,
451
+ target: RequestTargetOrId
452
+ ): void | (Record & Partial<RecordObject>) | Promise<void | (Record & Partial<RecordObject>)>;
453
+
454
+ delete?(target: RequestTargetOrId): boolean | Promise<boolean>;
455
+ invalidate?(target: RequestTargetOrId): void | Promise<void>;
456
+
457
+ publish?(target: RequestTargetOrId, record: Record, options?: any): void;
458
+ }
459
+
460
+ _assignPackageExport('Resource', Resource);
461
+
462
+ export function snakeCase(camelCase: string) {
463
+ return (
464
+ camelCase[0].toLowerCase() +
465
+ camelCase.slice(1).replace(/[a-z][A-Z][a-z]/g, (letters) => letters[0] + '_' + letters.slice(1))
466
+ );
467
+ }
468
+
469
+ /**
470
+ * This is responsible for arranging arguments in the main static methods and creating the appropriate context and default transaction wrapping
471
+ * @param action
472
+ * @param options
473
+ * @returns
474
+ */
475
+ function transactional(
476
+ action: (resource: ResourceInterface, query: RequestTarget, context: Context, data: any) => any,
477
+ options: {
478
+ hasContent: boolean;
479
+ type: 'read' | 'update' | 'create' | 'delete';
480
+ async?: boolean;
481
+ ensureLoaded?: boolean;
482
+ }
483
+ ) {
484
+ applyContext.reliesOnPrototype = true;
485
+ const hasContent = options.hasContent;
486
+ return applyContext;
487
+ function applyContext(idOrQuery: string | Id | Query, dataOrContext?: any, context?: Context) {
488
+ let id, query, isCollection;
489
+ let data;
490
+ // First we do our argument normalization. There are two main types of methods, with or without content
491
+ if (hasContent) {
492
+ // for put, post, patch, publish, query
493
+ if (context) {
494
+ // if there are three arguments, it is id, data, context
495
+ data = dataOrContext;
496
+ context = context.getContext?.() || context;
497
+ } else if (dataOrContext) {
498
+ // two arguments, more possibilities:
499
+ if (
500
+ typeof idOrQuery === 'object' &&
501
+ idOrQuery &&
502
+ (!Array.isArray(idOrQuery) || typeof idOrQuery[0] === 'object')
503
+ ) {
504
+ // (data, context) form
505
+ data = idOrQuery;
506
+ id = data[this.primaryKey] ?? null;
507
+ context = dataOrContext.getContext?.() || dataOrContext;
508
+ } else if (dataOrContext?.transaction instanceof DatabaseTransaction) {
509
+ // (id, context) form
510
+ context = dataOrContext;
511
+ } else {
512
+ // (id, data) form
513
+ data = dataOrContext;
514
+ }
515
+ } else if (idOrQuery && typeof idOrQuery === 'object') {
516
+ // single argument form, just data
517
+ data = idOrQuery;
518
+ idOrQuery = undefined;
519
+ id = data.getId?.() ?? data[this.primaryKey];
520
+ } else {
521
+ throw new ClientError(`Invalid argument for data, must be an object, but got ${idOrQuery}`);
522
+ }
523
+ if (id === null) isCollection = true;
524
+ // otherwise handle methods for get, delete, etc.
525
+ // first, check to see if it is two argument
526
+ } else if (dataOrContext) {
527
+ if (context) {
528
+ // (id, data, context), this a method that doesn't normally have a body/data, but with the three arguments, we have explicit data
529
+ data = dataOrContext;
530
+ context = context.getContext?.() || context;
531
+ } else if (hasContent === false) {
532
+ // (id, context), preferred form used for methods that are explicitly without a body
533
+ context = dataOrContext.getContext?.() || dataOrContext;
534
+ } else if (dataOrContext.transaction || dataOrContext.getContext) {
535
+ // or if it looks like a context
536
+ context = dataOrContext.getContext?.() || dataOrContext;
537
+ } else {
538
+ data = dataOrContext;
539
+ }
540
+ }
541
+ if (id === undefined) {
542
+ if (typeof idOrQuery === 'object' && idOrQuery) {
543
+ // it is a query
544
+ query = idOrQuery;
545
+ if (idOrQuery instanceof URLSearchParams) {
546
+ // already RequestTarget (or URLSearchParams), consider it already parsed,
547
+ // we can just do property parsing, coerce, and assign the id
548
+ id = idOrQuery.id;
549
+ if (this.directURLMapping) {
550
+ id = idOrQuery.toString().slice(1); // remove the leading slash
551
+ query.id = id;
552
+ } else if (typeof id === 'string') {
553
+ // handle paths of the form /path/id.property
554
+ const parsedId = this.parsePath(id, context, query);
555
+ if (parsedId?.id !== undefined) {
556
+ query.property = parsedId.property;
557
+ id = parsedId.id;
558
+ } else {
559
+ id = parsedId;
560
+ }
561
+ if (id) {
562
+ query.id = id = this.coerceId(id);
563
+ }
564
+ }
565
+ } else if (idOrQuery[Symbol.iterator]) {
566
+ // get the id part from an iterable query
567
+ id = [];
568
+ isCollection = true;
569
+ for (const part of idOrQuery) {
570
+ if (typeof part === 'object' && part) break;
571
+ id.push(part);
572
+ }
573
+ if (id.length === 0) id = null;
574
+ else {
575
+ if (id.length === 1) id = id[0];
576
+ if (query.slice) {
577
+ query = query.slice(id.length, query.length);
578
+ if (query.length === 0) {
579
+ query = new RequestTarget();
580
+ query.id = id;
581
+ }
582
+ }
583
+ }
584
+ } else if (id === undefined) {
585
+ id = idOrQuery.id ?? null;
586
+ if (id == null) query.isCollection = true;
587
+ }
588
+ } else {
589
+ id = idOrQuery;
590
+ query = new RequestTarget();
591
+ query.id = id;
592
+ if (id == null) {
593
+ if (options.method === 'get') {
594
+ throw new Error(`Using an argument with a value of ${id} for ${options.method}, is not allowed`);
595
+ }
596
+ query.isCollection = true;
597
+ }
598
+ }
599
+ }
600
+ if (!query) {
601
+ query = new RequestTarget();
602
+ query.id = id;
603
+ }
604
+ isCollection = query.isCollection;
605
+ let resourceOptions;
606
+ if (!context) {
607
+ // try to get the context from the async context if possible
608
+ context = contextStorage.getStore() ?? {};
609
+ }
610
+ if (query.ensureLoaded != null || query.async || isCollection) {
611
+ resourceOptions = { ...options };
612
+ if (query.ensureLoaded != null) resourceOptions.ensureLoaded = query.ensureLoaded;
613
+ if (query.syncAllowed) resourceOptions.syncAllowed = query.syncAllowed;
614
+ if (isCollection) resourceOptions.isCollection = true;
615
+ } else resourceOptions = options;
616
+ const loadAsInstance = this.loadAsInstance;
617
+ if (context?.transaction) {
618
+ // we are already in a transaction, proceed
619
+ const resource = this.getResource(query, context, resourceOptions);
620
+ return resource.then
621
+ ? resource.then(authorizeActionOnResource)
622
+ : promiseNormalize(authorizeActionOnResource(resource), resourceOptions);
623
+ } else {
624
+ // start a transaction
625
+ return promiseNormalize(
626
+ transaction(context, () => {
627
+ // record what transaction we are starting from, so that if it times out, we can have an indication of the cause
628
+ context.transaction.startedFrom = {
629
+ resourceName: this.name,
630
+ method: options.method,
631
+ };
632
+ const resource = this.getResource(query, context, resourceOptions);
633
+ return resource.then ? resource.then(authorizeActionOnResource) : authorizeActionOnResource(resource);
634
+ }),
635
+ resourceOptions
636
+ );
637
+ }
638
+ function authorizeActionOnResource(resource: ResourceInterface) {
639
+ let checkPermission = false;
640
+ if (query.checkPermission) {
641
+ checkPermission = true;
642
+ // authorization has been requested, but only do it for this entry call
643
+ }
644
+ if (context.authorize) {
645
+ checkPermission = true;
646
+ // authorization has been requested, but only do it for this entry call
647
+ context.authorize = false;
648
+ query.checkPermission = true;
649
+ }
650
+ if (checkPermission) {
651
+ if (loadAsInstance !== false) {
652
+ // do permission checks, with allow methods
653
+ const allowed =
654
+ options.type === 'read'
655
+ ? resource.allowRead(context.user, query, context)
656
+ : options.type === 'update'
657
+ ? resource.doesExist?.() === false
658
+ ? resource.allowCreate(context.user, data, context)
659
+ : resource.allowUpdate(context.user, data, context)
660
+ : options.type === 'create'
661
+ ? resource.allowCreate(context.user, data, context)
662
+ : resource.allowDelete(context.user, query, context);
663
+ if (allowed?.then) {
664
+ return allowed.then((allowed) => {
665
+ query.checkPermission = false;
666
+ if (!allowed) {
667
+ throw new AccessViolation(context.user);
668
+ }
669
+ return when(data, (data) => {
670
+ return action(resource, query, context, data);
671
+ });
672
+ });
673
+ }
674
+ query.checkPermission = false;
675
+ if (!allowed) {
676
+ throw new AccessViolation(context.user);
677
+ }
678
+ }
679
+ }
680
+ return when(data, (data) => {
681
+ return action(resource, query, context, data);
682
+ });
683
+ }
684
+ }
685
+ }
686
+ function missingMethod(resource, method) {
687
+ const error = new ClientError(`The ${resource.constructor.name} does not have a ${method} method implemented`, 405);
688
+ error.allow = [];
689
+ error.method = method;
690
+ for (const method of ['get', 'put', 'post', 'delete', 'query', 'move', 'copy']) {
691
+ if (typeof resource[method] === 'function') error.allow.push(method);
692
+ }
693
+ throw error;
694
+ }
695
+ /**
696
+ * This is responsible for handling a select query parameter/call that selects specific
697
+ * properties from the returned record(s).
698
+ * @param object
699
+ * @returns
700
+ */
701
+ function selectFromObject(object, propertyResolvers, context) {
702
+ // TODO: eventually we will do aggregate functions here
703
+ const record = object.getRecord?.();
704
+ if (record) {
705
+ const ownData = object.getChanges?.();
706
+ return (property) => {
707
+ let value, resolver;
708
+ if (object.hasOwnProperty(property) && typeof (value = object[property]) !== 'function') {
709
+ return value;
710
+ }
711
+ if (ownData && property in ownData) {
712
+ return ownData[property];
713
+ } else if ((resolver = propertyResolvers?.[property])) {
714
+ return resolver(object, context);
715
+ } else return record[property];
716
+ };
717
+ } else if (propertyResolvers) {
718
+ return (property) => {
719
+ const resolver = propertyResolvers[property];
720
+ return resolver ? resolver(object, context) : object[property];
721
+ };
722
+ } else return (property) => object[property];
723
+ }
724
+ export function transformForSelect(select, resource) {
725
+ const propertyResolvers = resource.propertyResolvers;
726
+ const context = resource.getContext?.();
727
+ let subTransforms;
728
+ if (typeof select === 'string')
729
+ // if select is a single string then return property value
730
+ return function transform(object) {
731
+ if (object.then) return object.then(transform);
732
+ if (Array.isArray(object)) return object.map(transform);
733
+ return selectFromObject(object, propertyResolvers, context)(select);
734
+ };
735
+ else if (typeof select === 'object') {
736
+ // if it is an array, return an array
737
+ if (select.asArray)
738
+ return function transform(object) {
739
+ if (object.then) return object.then(transform);
740
+ if (Array.isArray(object)) return object.map(transform);
741
+ const results = [];
742
+ const getProperty = handleProperty(selectFromObject(object, propertyResolvers, context));
743
+ for (const property of select) {
744
+ results.push(getProperty(property));
745
+ }
746
+ return results;
747
+ };
748
+ const forceNulls = select.forceNulls;
749
+ return function transform(object) {
750
+ if (object.then) return object.then(transform);
751
+ if (Array.isArray(object))
752
+ return object.map((value) => (value && typeof value === 'object' ? transform(value) : value));
753
+ // finally the case of returning objects
754
+ const selectedData = {};
755
+ const getProperty = handleProperty(selectFromObject(object, propertyResolvers, context));
756
+ let promises;
757
+ for (const property of select) {
758
+ let value = getProperty(property);
759
+ if (value === undefined && forceNulls) value = null;
760
+ if (value?.then) {
761
+ if (!promises) promises = [];
762
+ promises.push(value.then((value) => (selectedData[property.name || property] = value)));
763
+ } else selectedData[property.name || property] = value;
764
+ }
765
+ if (promises) return Promise.all(promises).then(() => selectedData);
766
+ return selectedData;
767
+ };
768
+ } else throw new Error('Invalid select argument type ' + typeof select);
769
+ function handleProperty(getProperty) {
770
+ return (property) => {
771
+ if (typeof property === 'string') {
772
+ return getProperty(property);
773
+ } else if (typeof property === 'object') {
774
+ // TODO: Handle aggregate functions
775
+ if (property.name) {
776
+ if (!subTransforms) subTransforms = {};
777
+ // TODO: Get the resource, cache this transform, and apply above
778
+ let transform = subTransforms[property.name];
779
+ if (!transform) {
780
+ const resource = propertyResolvers[property.name]?.definition?.tableClass;
781
+ transform = subTransforms[property.name] = transformForSelect(property.select || property, resource);
782
+ }
783
+ const value = getProperty(property.name);
784
+ return transform(value);
785
+ } else return getProperty(property);
786
+ } else return property;
787
+ };
788
+ }
789
+ }