harper 5.1.20 → 5.2.0-alpha.5

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 (395) hide show
  1. package/agent/operations.ts +13 -16
  2. package/components/Application.ts +188 -7
  3. package/components/ApplicationScope.ts +3 -0
  4. package/components/Scope.ts +12 -0
  5. package/components/anthropic/index.ts +9 -2
  6. package/components/bedrock/index.ts +25 -2
  7. package/components/componentLoader.ts +56 -7
  8. package/components/componentSecrets.ts +451 -0
  9. package/components/deploymentRecorder.ts +7 -1
  10. package/components/mcp/adapters/fastify.ts +3 -0
  11. package/components/mcp/adapters/harperHttp.ts +3 -0
  12. package/components/mcp/audit.ts +21 -6
  13. package/components/mcp/customResourceRegistry.ts +17 -38
  14. package/components/mcp/listChanged.ts +37 -20
  15. package/components/mcp/quota.ts +145 -0
  16. package/components/mcp/rateLimit.ts +152 -14
  17. package/components/mcp/resources.ts +2 -4
  18. package/components/mcp/toolRegistry.ts +73 -4
  19. package/components/mcp/tools/application.ts +77 -8
  20. package/components/mcp/tools/operations.ts +106 -36
  21. package/components/mcp/tools/schemas/operationDescriptions.ts +4 -4
  22. package/components/mcp/tools/schemas/operations.ts +5 -0
  23. package/components/mcp/transport.ts +55 -4
  24. package/components/ollama/index.ts +6 -2
  25. package/components/openai/index.ts +9 -2
  26. package/components/operations.js +204 -10
  27. package/components/operationsValidation.js +173 -0
  28. package/components/secretOperations.ts +498 -0
  29. package/config/configUtils.ts +25 -1
  30. package/config-app.schema.json +81 -0
  31. package/config-root.schema.json +8 -1
  32. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +4 -3
  33. package/dataLayer/readAuditLog.ts +14 -0
  34. package/dataLayer/schemaDescribe.ts +1 -0
  35. package/dist/agent/operations.d.ts +7 -4
  36. package/dist/agent/operations.js +13 -15
  37. package/dist/agent/operations.js.map +1 -1
  38. package/dist/components/Application.d.ts +25 -2
  39. package/dist/components/Application.js +166 -7
  40. package/dist/components/Application.js.map +1 -1
  41. package/dist/components/ApplicationScope.d.ts +2 -0
  42. package/dist/components/ApplicationScope.js +3 -0
  43. package/dist/components/ApplicationScope.js.map +1 -1
  44. package/dist/components/Scope.d.ts +8 -0
  45. package/dist/components/Scope.js +11 -0
  46. package/dist/components/Scope.js.map +1 -1
  47. package/dist/components/anthropic/index.d.ts +4 -1
  48. package/dist/components/anthropic/index.js +4 -2
  49. package/dist/components/anthropic/index.js.map +1 -1
  50. package/dist/components/bedrock/index.d.ts +4 -1
  51. package/dist/components/bedrock/index.js +22 -2
  52. package/dist/components/bedrock/index.js.map +1 -1
  53. package/dist/components/componentLoader.d.ts +2 -0
  54. package/dist/components/componentLoader.js +52 -10
  55. package/dist/components/componentLoader.js.map +1 -1
  56. package/dist/components/componentSecrets.d.ts +63 -0
  57. package/dist/components/componentSecrets.js +405 -0
  58. package/dist/components/componentSecrets.js.map +1 -0
  59. package/dist/components/deploymentRecorder.d.ts +3 -0
  60. package/dist/components/deploymentRecorder.js +4 -3
  61. package/dist/components/deploymentRecorder.js.map +1 -1
  62. package/dist/components/mcp/adapters/fastify.d.ts +2 -0
  63. package/dist/components/mcp/adapters/fastify.js +1 -0
  64. package/dist/components/mcp/adapters/fastify.js.map +1 -1
  65. package/dist/components/mcp/adapters/harperHttp.d.ts +2 -0
  66. package/dist/components/mcp/adapters/harperHttp.js +1 -0
  67. package/dist/components/mcp/adapters/harperHttp.js.map +1 -1
  68. package/dist/components/mcp/audit.d.ts +2 -2
  69. package/dist/components/mcp/audit.js +20 -5
  70. package/dist/components/mcp/audit.js.map +1 -1
  71. package/dist/components/mcp/customResourceRegistry.d.ts +5 -12
  72. package/dist/components/mcp/customResourceRegistry.js +15 -30
  73. package/dist/components/mcp/customResourceRegistry.js.map +1 -1
  74. package/dist/components/mcp/listChanged.d.ts +7 -2
  75. package/dist/components/mcp/listChanged.js +28 -0
  76. package/dist/components/mcp/listChanged.js.map +1 -1
  77. package/dist/components/mcp/quota.d.ts +31 -0
  78. package/dist/components/mcp/quota.js +155 -0
  79. package/dist/components/mcp/quota.js.map +1 -0
  80. package/dist/components/mcp/rateLimit.d.ts +19 -3
  81. package/dist/components/mcp/rateLimit.js +129 -13
  82. package/dist/components/mcp/rateLimit.js.map +1 -1
  83. package/dist/components/mcp/resources.js.map +1 -1
  84. package/dist/components/mcp/toolRegistry.d.ts +39 -1
  85. package/dist/components/mcp/toolRegistry.js +60 -5
  86. package/dist/components/mcp/toolRegistry.js.map +1 -1
  87. package/dist/components/mcp/tools/application.d.ts +8 -1
  88. package/dist/components/mcp/tools/application.js +65 -5
  89. package/dist/components/mcp/tools/application.js.map +1 -1
  90. package/dist/components/mcp/tools/operations.d.ts +15 -3
  91. package/dist/components/mcp/tools/operations.js +99 -38
  92. package/dist/components/mcp/tools/operations.js.map +1 -1
  93. package/dist/components/mcp/tools/schemas/operationDescriptions.js +4 -4
  94. package/dist/components/mcp/tools/schemas/operationDescriptions.js.map +1 -1
  95. package/dist/components/mcp/tools/schemas/operations.js +4 -0
  96. package/dist/components/mcp/tools/schemas/operations.js.map +1 -1
  97. package/dist/components/mcp/transport.d.ts +6 -0
  98. package/dist/components/mcp/transport.js +47 -3
  99. package/dist/components/mcp/transport.js.map +1 -1
  100. package/dist/components/ollama/index.d.ts +4 -1
  101. package/dist/components/ollama/index.js +4 -2
  102. package/dist/components/ollama/index.js.map +1 -1
  103. package/dist/components/openai/index.d.ts +4 -1
  104. package/dist/components/openai/index.js +4 -2
  105. package/dist/components/openai/index.js.map +1 -1
  106. package/dist/components/operations.d.ts +39 -0
  107. package/dist/components/operations.js +194 -2
  108. package/dist/components/operations.js.map +1 -1
  109. package/dist/components/operationsValidation.d.ts +38 -0
  110. package/dist/components/operationsValidation.js +155 -0
  111. package/dist/components/operationsValidation.js.map +1 -1
  112. package/dist/components/secretOperations.d.ts +113 -0
  113. package/dist/components/secretOperations.js +475 -0
  114. package/dist/components/secretOperations.js.map +1 -0
  115. package/dist/config/configUtils.d.ts +4 -1
  116. package/dist/config/configUtils.js +18 -1
  117. package/dist/config/configUtils.js.map +1 -1
  118. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +4 -3
  119. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js.map +1 -1
  120. package/dist/dataLayer/readAuditLog.js +11 -0
  121. package/dist/dataLayer/readAuditLog.js.map +1 -1
  122. package/dist/dataLayer/schemaDescribe.js +2 -0
  123. package/dist/dataLayer/schemaDescribe.js.map +1 -1
  124. package/dist/globals.d.ts +1 -1
  125. package/dist/globals.js +1 -0
  126. package/dist/globals.js.map +1 -1
  127. package/dist/index.d.ts +3 -0
  128. package/dist/index.js +1 -0
  129. package/dist/index.js.map +1 -1
  130. package/dist/json/systemSchema.json +38 -0
  131. package/dist/resources/DatabaseTransaction.d.ts +31 -3
  132. package/dist/resources/DatabaseTransaction.js +190 -29
  133. package/dist/resources/DatabaseTransaction.js.map +1 -1
  134. package/dist/resources/LMDBTransaction.d.ts +1 -1
  135. package/dist/resources/LMDBTransaction.js +43 -5
  136. package/dist/resources/LMDBTransaction.js.map +1 -1
  137. package/dist/resources/PrimaryRocksDatabase.d.ts +51 -0
  138. package/dist/resources/PrimaryRocksDatabase.js +194 -0
  139. package/dist/resources/PrimaryRocksDatabase.js.map +1 -0
  140. package/dist/resources/RecordEncoder.d.ts +1 -0
  141. package/dist/resources/RecordEncoder.js +81 -75
  142. package/dist/resources/RecordEncoder.js.map +1 -1
  143. package/dist/resources/RequestTarget.d.ts +19 -0
  144. package/dist/resources/RequestTarget.js.map +1 -1
  145. package/dist/resources/Resource.d.ts +0 -1
  146. package/dist/resources/Resource.js +103 -16
  147. package/dist/resources/Resource.js.map +1 -1
  148. package/dist/resources/ResourceInterface.d.ts +6 -2
  149. package/dist/resources/ResourceInterface.js.map +1 -1
  150. package/dist/resources/Resources.js.map +1 -1
  151. package/dist/resources/Table.d.ts +6 -4
  152. package/dist/resources/Table.js +247 -24
  153. package/dist/resources/Table.js.map +1 -1
  154. package/dist/resources/analytics/read.js +25 -28
  155. package/dist/resources/analytics/read.js.map +1 -1
  156. package/dist/resources/blob.js +165 -22
  157. package/dist/resources/blob.js.map +1 -1
  158. package/dist/resources/crdt.d.ts +2 -0
  159. package/dist/resources/crdt.js +45 -36
  160. package/dist/resources/crdt.js.map +1 -1
  161. package/dist/resources/databases.d.ts +1 -0
  162. package/dist/resources/databases.js +134 -7
  163. package/dist/resources/databases.js.map +1 -1
  164. package/dist/resources/graphql.js +8 -0
  165. package/dist/resources/graphql.js.map +1 -1
  166. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +35 -5
  167. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +239 -14
  168. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
  169. package/dist/resources/jsResource.js +6 -0
  170. package/dist/resources/jsResource.js.map +1 -1
  171. package/dist/resources/loadEnv.js +30 -3
  172. package/dist/resources/loadEnv.js.map +1 -1
  173. package/dist/resources/login.js +2 -2
  174. package/dist/resources/login.js.map +1 -1
  175. package/dist/resources/models/Models.js +14 -3
  176. package/dist/resources/models/Models.js.map +1 -1
  177. package/dist/resources/models/embedHook.js +10 -2
  178. package/dist/resources/models/embedHook.js.map +1 -1
  179. package/dist/resources/models/openaiStream.d.ts +56 -0
  180. package/dist/resources/models/openaiStream.js +94 -0
  181. package/dist/resources/models/openaiStream.js.map +1 -0
  182. package/dist/resources/replayLogs.js +4 -3
  183. package/dist/resources/replayLogs.js.map +1 -1
  184. package/dist/resources/search.d.ts +1 -1
  185. package/dist/resources/search.js +104 -11
  186. package/dist/resources/search.js.map +1 -1
  187. package/dist/resources/secretDecryptor.d.ts +54 -0
  188. package/dist/resources/secretDecryptor.js +131 -0
  189. package/dist/resources/secretDecryptor.js.map +1 -0
  190. package/dist/resources/tracked.js +15 -5
  191. package/dist/resources/tracked.js.map +1 -1
  192. package/dist/security/auth.js +71 -8
  193. package/dist/security/auth.js.map +1 -1
  194. package/dist/security/jsLoader.js +11 -0
  195. package/dist/security/jsLoader.js.map +1 -1
  196. package/dist/security/tokenAuthentication.d.ts +9 -1
  197. package/dist/security/tokenAuthentication.js +31 -1
  198. package/dist/security/tokenAuthentication.js.map +1 -1
  199. package/dist/server/DurableSubscriptionsSession.d.ts +1 -1
  200. package/dist/server/DurableSubscriptionsSession.js +8 -4
  201. package/dist/server/DurableSubscriptionsSession.js.map +1 -1
  202. package/dist/server/REST.js +28 -9
  203. package/dist/server/REST.js.map +1 -1
  204. package/dist/server/fastifyRoutes.js +11 -1
  205. package/dist/server/fastifyRoutes.js.map +1 -1
  206. package/dist/server/graphqlQuerying.js +4 -3
  207. package/dist/server/graphqlQuerying.js.map +1 -1
  208. package/dist/server/http.d.ts +40 -2
  209. package/dist/server/http.js +560 -77
  210. package/dist/server/http.js.map +1 -1
  211. package/dist/server/itc/serverHandlers.js +64 -0
  212. package/dist/server/itc/serverHandlers.js.map +1 -1
  213. package/dist/server/liveSubscriptionAuth.d.ts +12 -0
  214. package/dist/server/liveSubscriptionAuth.js +140 -0
  215. package/dist/server/liveSubscriptionAuth.js.map +1 -0
  216. package/dist/server/loadRootComponents.js +2 -1
  217. package/dist/server/loadRootComponents.js.map +1 -1
  218. package/dist/server/middlewareChain.d.ts +44 -1
  219. package/dist/server/middlewareChain.js +86 -10
  220. package/dist/server/middlewareChain.js.map +1 -1
  221. package/dist/server/mqtt.js +2 -1
  222. package/dist/server/mqtt.js.map +1 -1
  223. package/dist/server/operationsServer.js +1 -1
  224. package/dist/server/operationsServer.js.map +1 -1
  225. package/dist/server/serverHelpers/Headers.d.ts +9 -0
  226. package/dist/server/serverHelpers/Headers.js +22 -0
  227. package/dist/server/serverHelpers/Headers.js.map +1 -1
  228. package/dist/server/serverHelpers/JSONStream.js +3 -3
  229. package/dist/server/serverHelpers/JSONStream.js.map +1 -1
  230. package/dist/server/serverHelpers/Request.d.ts +52 -1
  231. package/dist/server/serverHelpers/Request.js +122 -1
  232. package/dist/server/serverHelpers/Request.js.map +1 -1
  233. package/dist/server/serverHelpers/contentTypes.js +3 -8
  234. package/dist/server/serverHelpers/contentTypes.js.map +1 -1
  235. package/dist/server/serverHelpers/progressEmitter.d.ts +19 -0
  236. package/dist/server/serverHelpers/progressEmitter.js +52 -4
  237. package/dist/server/serverHelpers/progressEmitter.js.map +1 -1
  238. package/dist/server/serverHelpers/registeredOperations.d.ts +40 -0
  239. package/dist/server/serverHelpers/registeredOperations.js +286 -0
  240. package/dist/server/serverHelpers/registeredOperations.js.map +1 -0
  241. package/dist/server/serverHelpers/serverHandlers.js +11 -5
  242. package/dist/server/serverHelpers/serverHandlers.js.map +1 -1
  243. package/dist/server/serverHelpers/serverUtilities.d.ts +1 -0
  244. package/dist/server/serverHelpers/serverUtilities.js +67 -5
  245. package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
  246. package/dist/server/serverHelpers/uwsServer.d.ts +80 -0
  247. package/dist/server/serverHelpers/uwsServer.js +433 -0
  248. package/dist/server/serverHelpers/uwsServer.js.map +1 -0
  249. package/dist/server/static.d.ts +0 -15
  250. package/dist/server/static.js +161 -2
  251. package/dist/server/static.js.map +1 -1
  252. package/dist/server/status/index.d.ts +4 -1
  253. package/dist/server/status/index.js +64 -4
  254. package/dist/server/status/index.js.map +1 -1
  255. package/dist/server/threads/manageThreads.d.ts +10 -0
  256. package/dist/server/threads/manageThreads.js +107 -4
  257. package/dist/server/threads/manageThreads.js.map +1 -1
  258. package/dist/server/threads/socketRouter.js +5 -1
  259. package/dist/server/threads/socketRouter.js.map +1 -1
  260. package/dist/server/threads/threadServer.js +92 -14
  261. package/dist/server/threads/threadServer.js.map +1 -1
  262. package/dist/upgrade/directives/5-2-0.d.ts +7 -0
  263. package/dist/upgrade/directives/5-2-0.js +108 -0
  264. package/dist/upgrade/directives/5-2-0.js.map +1 -0
  265. package/dist/upgrade/directives/directivesController.js +2 -1
  266. package/dist/upgrade/directives/directivesController.js.map +1 -1
  267. package/dist/utility/common_utils.js +5 -0
  268. package/dist/utility/common_utils.js.map +1 -1
  269. package/dist/utility/envFile.d.ts +41 -0
  270. package/dist/utility/envFile.js +221 -0
  271. package/dist/utility/envFile.js.map +1 -0
  272. package/dist/utility/globalSchema.d.ts +9 -0
  273. package/dist/utility/hdbTerms.d.ts +25 -0
  274. package/dist/utility/hdbTerms.js +31 -0
  275. package/dist/utility/hdbTerms.js.map +1 -1
  276. package/dist/utility/logging/harper_logger.d.ts +21 -0
  277. package/dist/utility/logging/harper_logger.js +160 -8
  278. package/dist/utility/logging/harper_logger.js.map +1 -1
  279. package/dist/utility/logging/logRotator.js +29 -17
  280. package/dist/utility/logging/logRotator.js.map +1 -1
  281. package/dist/utility/logging/readLog.d.ts +1 -1
  282. package/dist/utility/logging/readLog.js +305 -2
  283. package/dist/utility/logging/readLog.js.map +1 -1
  284. package/dist/utility/operationPermissions.d.ts +18 -0
  285. package/dist/utility/operationPermissions.js +35 -1
  286. package/dist/utility/operationPermissions.js.map +1 -1
  287. package/dist/utility/operation_authorization.d.ts +17 -0
  288. package/dist/utility/operation_authorization.js +38 -0
  289. package/dist/utility/operation_authorization.js.map +1 -1
  290. package/dist/utility/secretEnvelope.d.ts +30 -0
  291. package/dist/utility/secretEnvelope.js +94 -0
  292. package/dist/utility/secretEnvelope.js.map +1 -0
  293. package/dist/utility/signalling.d.ts +7 -0
  294. package/dist/utility/signalling.js +16 -0
  295. package/dist/utility/signalling.js.map +1 -1
  296. package/dist/validation/configValidator.js +70 -24
  297. package/dist/validation/configValidator.js.map +1 -1
  298. package/index.ts +4 -0
  299. package/json/systemSchema.json +38 -0
  300. package/npm-shrinkwrap.json +15066 -9347
  301. package/package.json +13 -8
  302. package/resources/DESIGN.md +15 -12
  303. package/resources/DatabaseTransaction.ts +206 -37
  304. package/resources/LMDBTransaction.ts +43 -9
  305. package/resources/PrimaryRocksDatabase.ts +201 -0
  306. package/resources/RecordEncoder.ts +81 -69
  307. package/resources/RequestTarget.ts +21 -0
  308. package/resources/Resource.ts +109 -25
  309. package/resources/ResourceInterface.ts +6 -2
  310. package/resources/Resources.ts +1 -3
  311. package/resources/Table.ts +238 -29
  312. package/resources/analytics/read.ts +25 -30
  313. package/resources/blob.ts +159 -23
  314. package/resources/crdt.ts +37 -31
  315. package/resources/databases.ts +143 -6
  316. package/resources/graphql.ts +8 -0
  317. package/resources/indexes/HierarchicalNavigableSmallWorld.ts +251 -17
  318. package/resources/jsResource.ts +6 -0
  319. package/resources/loadEnv.ts +34 -3
  320. package/resources/login.ts +2 -2
  321. package/resources/models/Models.ts +19 -3
  322. package/resources/models/embedHook.ts +13 -2
  323. package/resources/models/openaiStream.ts +133 -0
  324. package/resources/replayLogs.ts +4 -3
  325. package/resources/search.ts +113 -11
  326. package/resources/secretDecryptor.ts +159 -0
  327. package/resources/tracked.ts +24 -17
  328. package/security/auth.ts +70 -10
  329. package/security/jsLoader.ts +12 -0
  330. package/security/tokenAuthentication.ts +42 -1
  331. package/server/DESIGN.md +10 -0
  332. package/server/DurableSubscriptionsSession.ts +8 -4
  333. package/server/REST.ts +26 -9
  334. package/server/fastifyRoutes.ts +10 -1
  335. package/server/graphqlQuerying.ts +4 -3
  336. package/server/http.ts +563 -77
  337. package/server/itc/serverHandlers.js +70 -0
  338. package/server/liveSubscriptionAuth.ts +152 -0
  339. package/server/loadRootComponents.js +2 -1
  340. package/server/middlewareChain.ts +107 -17
  341. package/server/mqtt.ts +2 -1
  342. package/server/operationsServer.ts +2 -2
  343. package/server/serverHelpers/Headers.ts +24 -0
  344. package/server/serverHelpers/JSONStream.ts +3 -3
  345. package/server/serverHelpers/Request.ts +127 -0
  346. package/server/serverHelpers/contentTypes.ts +3 -8
  347. package/server/serverHelpers/progressEmitter.ts +55 -5
  348. package/server/serverHelpers/registeredOperations.ts +259 -0
  349. package/server/serverHelpers/serverHandlers.js +11 -5
  350. package/server/serverHelpers/serverUtilities.ts +88 -5
  351. package/server/serverHelpers/uwsServer.ts +488 -0
  352. package/server/static.ts +180 -2
  353. package/server/status/index.ts +72 -4
  354. package/server/threads/manageThreads.js +102 -4
  355. package/server/threads/socketRouter.ts +5 -1
  356. package/server/threads/threadServer.js +93 -10
  357. package/studio/web/assets/{Chat-SdD1EZca.js → Chat-Cv_2paZE.js} +2 -2
  358. package/studio/web/assets/{Chat-SdD1EZca.js.map → Chat-Cv_2paZE.js.map} +1 -1
  359. package/studio/web/assets/{FloatingChat-GMq6tHK9.js → FloatingChat-CPyPIcVR.js} +4 -4
  360. package/studio/web/assets/{FloatingChat-GMq6tHK9.js.map → FloatingChat-CPyPIcVR.js.map} +1 -1
  361. package/studio/web/assets/{applications-B5hhv7uA.js → applications-C0jT2vdZ.js} +2 -2
  362. package/studio/web/assets/{applications-B5hhv7uA.js.map → applications-C0jT2vdZ.js.map} +1 -1
  363. package/studio/web/assets/{index-VFcpNWgq.js → index-D_GKOkhn.js} +6 -6
  364. package/studio/web/assets/index-D_GKOkhn.js.map +1 -0
  365. package/studio/web/assets/{index.lazy-DgcJojIA.js → index.lazy-CAmCIA65.js} +4 -4
  366. package/studio/web/assets/{index.lazy-DgcJojIA.js.map → index.lazy-CAmCIA65.js.map} +1 -1
  367. package/studio/web/assets/{profile-BqN-8vzm.js → profile-CaF-4aZe.js} +2 -2
  368. package/studio/web/assets/{profile-BqN-8vzm.js.map → profile-CaF-4aZe.js.map} +1 -1
  369. package/studio/web/assets/{setComponentFile-CHFvFq9u.js → setComponentFile-DLW1DHCt.js} +2 -2
  370. package/studio/web/assets/{setComponentFile-CHFvFq9u.js.map → setComponentFile-DLW1DHCt.js.map} +1 -1
  371. package/studio/web/assets/{setup-CQ3vWJSr.js → setup-TGCErIhq.js} +2 -2
  372. package/studio/web/assets/{setup-CQ3vWJSr.js.map → setup-TGCErIhq.js.map} +1 -1
  373. package/studio/web/assets/{status-BsW5fjuh.js → status-DG0Maoao.js} +2 -2
  374. package/studio/web/assets/{status-BsW5fjuh.js.map → status-DG0Maoao.js.map} +1 -1
  375. package/studio/web/assets/{swagger-ui-react-DITdeB9-.js → swagger-ui-react-8T4SgQ1m.js} +2 -2
  376. package/studio/web/assets/{swagger-ui-react-DITdeB9-.js.map → swagger-ui-react-8T4SgQ1m.js.map} +1 -1
  377. package/studio/web/assets/{tsMode-Dyph-OUs.js → tsMode-DJ6Sl24Q.js} +2 -2
  378. package/studio/web/assets/{tsMode-Dyph-OUs.js.map → tsMode-DJ6Sl24Q.js.map} +1 -1
  379. package/studio/web/assets/{useEntityRestURL-D0QTUqex.js → useEntityRestURL-JO2mfWTQ.js} +2 -2
  380. package/studio/web/assets/{useEntityRestURL-D0QTUqex.js.map → useEntityRestURL-JO2mfWTQ.js.map} +1 -1
  381. package/studio/web/index.html +1 -1
  382. package/upgrade/directives/5-2-0.ts +82 -0
  383. package/upgrade/directives/directivesController.ts +2 -1
  384. package/utility/common_utils.ts +5 -0
  385. package/utility/envFile.ts +218 -0
  386. package/utility/hdbTerms.ts +31 -0
  387. package/utility/logging/harper_logger.ts +156 -8
  388. package/utility/logging/logRotator.ts +24 -14
  389. package/utility/logging/readLog.ts +323 -2
  390. package/utility/operationPermissions.ts +35 -1
  391. package/utility/operation_authorization.ts +74 -1
  392. package/utility/secretEnvelope.ts +113 -0
  393. package/utility/signalling.ts +15 -0
  394. package/validation/configValidator.ts +78 -25
  395. package/studio/web/assets/index-VFcpNWgq.js.map +0 -1
package/resources/blob.ts CHANGED
@@ -34,7 +34,7 @@ import {
34
34
  type FSWatcher,
35
35
  } from 'node:fs';
36
36
  import type { StatsFs } from 'node:fs';
37
- import { createDeflate, createInflate, deflate } from 'node:zlib';
37
+ import { createDeflate, createInflate, inflate } from 'node:zlib';
38
38
  import { Readable, pipeline } from 'node:stream';
39
39
  import { ensureDirSync } from 'fs-extra';
40
40
  import { get as envGet, getHdbBasePath } from '../utility/environment/environmentManager.ts';
@@ -294,11 +294,17 @@ class FileBackedBlob extends (Blob as unknown as { new (): Blob }) implements Bl
294
294
  rawBytes = Buffer.alloc(0);
295
295
  fileMissing = true;
296
296
  }
297
- function checkCompletion(rawBytes: Buffer): Buffer | Promise<Buffer> {
298
- if (size > rawBytes.length) {
299
- // the file is not finished being written, wait for the write lock to complete
300
- const store = storageInfo.store;
301
- const lockKey = storageInfo.fileId + ':blob';
297
+ // The file may still be mid-write. Wait for the writer's `:blob` lock to release, then re-read.
298
+ // `incomplete` is the caller's "definitely not done yet" signal: for an uncompressed blob the
299
+ // on-disk body length must reach the (uncompressed) header size. For a compressed blob the body
300
+ // is shorter than the uncompressed size AND the header size is finalized up front when the size
301
+ // is known, so neither is a reliable completeness signal — the writer's lock is. The caller
302
+ // passes `mustVerifyViaLock` for compressed blobs so we probe the lock even when the bytes look
303
+ // plausible, and only treat the file as complete once the writer is confirmed done.
304
+ function waitForCompletion(incomplete: boolean, mustVerifyViaLock = false): Promise<Buffer> | undefined {
305
+ const store = storageInfo.store;
306
+ const lockKey = storageInfo.fileId + ':blob';
307
+ if (incomplete) {
302
308
  if (writeFinished) {
303
309
  // the writer released its lock but the content is still short: the file is cleanly gone
304
310
  // (404) or confidently incomplete/corrupt (500) — not merely mid-write (#1423/#1424).
@@ -337,24 +343,77 @@ class FileBackedBlob extends (Blob as unknown as { new (): Blob }) implements Bl
337
343
  resolve(readContents());
338
344
  }
339
345
  });
346
+ } else if (mustVerifyViaLock && !writeFinished) {
347
+ // Bytes look complete but we can't prove it for a compressed body; probe whether the writer
348
+ // still holds the lock. If we acquire it, the write has finished, but the bytes we read may
349
+ // predate the final flush, so re-read once to get the complete body. Otherwise fall through
350
+ // to wait for the lock to release.
351
+ const acquiredImmediately = store.tryLock(lockKey);
352
+ if (acquiredImmediately) {
353
+ writeFinished = true;
354
+ store.unlock(lockKey);
355
+ return readContents(); // writer done — re-read to ensure we have the final bytes
356
+ }
357
+ } else {
358
+ return undefined; // confirmed complete (uncompressed exact-size match)
340
359
  }
360
+ return new Promise((resolve, reject) => {
361
+ let settled = false;
362
+ const timer = setTimeout(() => {
363
+ if (settled) return;
364
+ settled = true;
365
+ reject(
366
+ new BlobReadError(
367
+ `Blob ${storageInfo.fileId} is unavailable; the in-progress write did not complete in time`,
368
+ BLOB_UNAVAILABLE_STATUS
369
+ )
370
+ );
371
+ }, getBlobReadTimeout());
372
+ timer.unref();
373
+ const callback = () => {
374
+ if (settled) return;
375
+ settled = true;
376
+ clearTimeout(timer);
377
+ writeFinished = true;
378
+ resolve(readContents());
379
+ };
380
+ const lockAcquired = store.tryLock(lockKey, callback);
381
+ if (lockAcquired) {
382
+ settled = true;
383
+ clearTimeout(timer);
384
+ writeFinished = true;
385
+ store.unlock(lockKey);
386
+ resolve(readContents());
387
+ }
388
+ });
389
+ }
390
+ function sliceContent(bytes: Buffer): Buffer {
341
391
  if (end != undefined || start != undefined) {
342
- rawBytes = rawBytes.subarray(start ?? 0, end ?? rawBytes.length);
392
+ bytes = bytes.subarray(start ?? 0, end ?? bytes.length);
343
393
  }
344
- return rawBytes;
394
+ return bytes;
345
395
  }
346
396
  // Only sniff the storage-type byte and take the decompress branch when a full header is present.
347
397
  // A file shorter than the header (truncated/corrupted, #1424) would otherwise be mis-read as a
348
398
  // deflate body and yield garbage; instead it falls through to checkCompletion as incomplete.
349
399
  if (rawBytes.length >= HEADER_SIZE && rawBytes[1] === DEFLATE_TYPE) {
400
+ // An in-flight compressed file still carrying the UNKNOWN_SIZE placeholder is definitely
401
+ // incomplete; otherwise the size is finalized but the compressed body may still be streaming,
402
+ // so verify via the write lock before inflating (inflating a partial deflate stream errors).
403
+ const pending = waitForCompletion(size === UNKNOWN_SIZE, true);
404
+ if (pending) return pending;
350
405
  return new Promise<Buffer>((resolve, reject) => {
351
- deflate(rawBytes.subarray(HEADER_SIZE), (error, result) => {
406
+ // start/end index into the UNCOMPRESSED content, so inflate first, then slice
407
+ inflate(rawBytes.subarray(HEADER_SIZE), (error, result) => {
352
408
  if (error) reject(error);
353
- else resolve(checkCompletion(result));
409
+ else resolve(sliceContent(result));
354
410
  });
355
411
  });
356
412
  }
357
- return checkCompletion(rawBytes.subarray(HEADER_SIZE));
413
+ const body = rawBytes.subarray(HEADER_SIZE);
414
+ const pending = waitForCompletion(size > body.length);
415
+ if (pending) return pending;
416
+ return sliceContent(body);
358
417
  };
359
418
  return readContents();
360
419
  }
@@ -388,7 +447,24 @@ class FileBackedBlob extends (Blob as unknown as { new (): Blob }) implements Bl
388
447
  let totalContentRead = 0;
389
448
  let watcher: FSWatcher;
390
449
  let timer: NodeJS.Timeout;
450
+ // The start() open-retry timer lives in a different scope/phase than pull()'s `timer`; track it
451
+ // separately so a cancel() during the file-creation wait clears it instead of leaking an fd (#1457).
452
+ let openTimer: NodeJS.Timeout;
453
+ // Stream-wide cancellation gate. cancel() can null `fd` but cannot reach pull()'s per-pull
454
+ // `settled` flag, so this is the cross-phase signal that stops start()/pull() from opening or
455
+ // reading once the consumer has cancelled (e.g. an aborted ranged response) (#1457).
456
+ let cancelled = false;
391
457
  let isBeingWritten: boolean;
458
+ // Close the descriptor at most once. Without nulling `fd`, a later close()/cancel() (e.g. a
459
+ // GC-driven cancel after a successful read) would close a descriptor the OS may have reassigned to
460
+ // an unrelated file/socket; and a cancel() before start()'s open() resolves would call
461
+ // close(undefined) and throw. Guarding on `fd != null` fixes both (#1457).
462
+ const closeFd = () => {
463
+ if (fd != null) {
464
+ close(fd);
465
+ fd = null;
466
+ }
467
+ };
392
468
  let previouslyFinishedWriting = false;
393
469
  const blob = this;
394
470
  // Authoritative (uncompressed) content length from the record descriptor, captured before the
@@ -406,6 +482,7 @@ class FileBackedBlob extends (Blob as unknown as { new (): Blob }) implements Bl
406
482
  // lookup) is computed lazily on the first miss, so a healthy read never pays for it.
407
483
  let deadline = 0;
408
484
  const openFile = (resolve: (value: any) => void, reject: (error: Error) => void) => {
485
+ if (cancelled) return resolve(undefined); // consumer cancelled before/while opening; stop retrying
409
486
  open(filePath, 'r', (error, openedFd) => {
410
487
  if (error) {
411
488
  if (error.code === 'ENOENT' && isBeingWritten !== false) {
@@ -413,10 +490,11 @@ class FileBackedBlob extends (Blob as unknown as { new (): Blob }) implements Bl
413
490
  if (Date.now() < deadline) {
414
491
  logger.debug?.('File does not exist yet, waiting for it to be created', filePath);
415
492
  // the file doesn't exist, so we need to wait for it to be created
416
- return setTimeout(() => {
493
+ openTimer = setTimeout(() => {
417
494
  checkIfIsBeingWritten();
418
495
  openFile(resolve, reject);
419
496
  }, 20).unref();
497
+ return openTimer;
420
498
  }
421
499
  }
422
500
  // ENOENT: 503 if a local writer holds the lock or a replication receive is in
@@ -436,6 +514,9 @@ class FileBackedBlob extends (Blob as unknown as { new (): Blob }) implements Bl
436
514
  blob.#onError?.forEach((callback) => callback(readError));
437
515
  } else {
438
516
  fd = openedFd;
517
+ // the consumer cancelled while open() was in flight: pull()/cancel() will not run
518
+ // again, so close the descriptor we just acquired rather than leaking it (#1457)
519
+ if (cancelled) closeFd();
439
520
  resolve(openedFd);
440
521
  }
441
522
  });
@@ -450,9 +531,18 @@ class FileBackedBlob extends (Blob as unknown as { new (): Blob }) implements Bl
450
531
  // it; bounds the case where the header reports a known size but the bytes never arrive (a
451
532
  // present-but-truncated blob whose writer lock stays held) (#1454).
452
533
  let incompleteDeadline = 0;
534
+ // Settle this pull exactly once. A slow async read that completes with an error after the
535
+ // watcher-timeout path already called onError() (and closed the fd) would otherwise run
536
+ // onError twice — double close + duplicated #onError callbacks (#1457).
537
+ let settled = false;
453
538
  return new Promise(function readMore(resolve: () => void, reject: (error: Error) => void) {
539
+ // A queued timer/watcher callback can re-enter readMore after the stream was cancelled (fd
540
+ // is gone); stop here so we never issue read() on a closed/nulled descriptor (#1457).
541
+ if (cancelled || fd == null) return resolve();
454
542
  function onError(error) {
455
- close(fd);
543
+ if (settled) return;
544
+ settled = true;
545
+ closeFd();
456
546
  clearTimeout(timer);
457
547
  if (watcher) watcher.close();
458
548
  reject(error);
@@ -461,7 +551,11 @@ class FileBackedBlob extends (Blob as unknown as { new (): Blob }) implements Bl
461
551
  // allocate a buffer for reading. Note that we could do a stat to get the size, but that is a little more complicated, and might be a little extra overhead
462
552
  const buffer = Buffer.allocUnsafe(0x40000);
463
553
  read(fd, buffer, 0, buffer.length, position, (error, bytesRead, buffer) => {
464
- // TODO: Implement support for decompression
554
+ // A late read completion after the pull already settled (via onError or terminal
555
+ // close) or after the stream was cancelled (fd nulled, EBADF/partial read) must not
556
+ // re-enter the state machine — otherwise a recursive read() would hit a null fd and
557
+ // throw synchronously, or onError() would reject an already-cancelled stream (#1457).
558
+ if (settled || cancelled) return resolve();
465
559
  totalContentRead += bytesRead;
466
560
  if (error) return onError(error);
467
561
  if (position === 0) {
@@ -497,6 +591,36 @@ class FileBackedBlob extends (Blob as unknown as { new (): Blob }) implements Bl
497
591
  // half-replicated blob whose source stream aborted; the bytes are still expected — retry (harper-pro#481)
498
592
  return onError(new BlobReadError('Blob pending replication for ' + filePath, BLOB_UNAVAILABLE_STATUS));
499
593
  }
594
+ if (buffer[1] === DEFLATE_TYPE) {
595
+ // We can't seek/slice a deflate stream by uncompressed offset, so hand off to the
596
+ // buffered inflate path (bytes() inflates then slices) and emit it as one chunk.
597
+ // Safe by construction: the read loop never streams the raw compressed body.
598
+ return blob.bytes().then(
599
+ (bytes: Buffer) => {
600
+ // bytes() resolves asynchronously; the consumer may have cancelled meanwhile.
601
+ // Settle exactly once and route the close through closeFd() so we never touch a
602
+ // reassigned/nulled descriptor (#1457).
603
+ if (settled || cancelled) return resolve();
604
+ settled = true;
605
+ closeFd();
606
+ if (bytes.length > 0) {
607
+ try {
608
+ controller.enqueue(bytes);
609
+ } catch (error) {
610
+ logger.debug?.('Error enqueuing chunk', error);
611
+ return resolve();
612
+ }
613
+ }
614
+ try {
615
+ controller.close();
616
+ } catch {
617
+ // controller may already be closed
618
+ }
619
+ resolve();
620
+ },
621
+ (error: Error) => onError(error)
622
+ );
623
+ }
500
624
  size = Number(headerValue & 0xffffffffffffn);
501
625
  if (size < UNKNOWN_SIZE) {
502
626
  if (isFullRead && descriptorSize != null && descriptorSize < UNKNOWN_SIZE && size !== descriptorSize) {
@@ -522,6 +646,7 @@ class FileBackedBlob extends (Blob as unknown as { new (): Blob }) implements Bl
522
646
  } else if (bytesRead === 0) {
523
647
  const buffer = Buffer.allocUnsafe(8);
524
648
  return read(fd, buffer, 0, HEADER_SIZE, 0, (error) => {
649
+ if (settled || cancelled) return resolve();
525
650
  if (error) return onError(error);
526
651
  size = Number(new DataView(buffer.buffer, buffer.byteOffset, 8).getBigUint64(0) & 0xffffffffffffn);
527
652
  if (size > totalContentRead) {
@@ -621,7 +746,8 @@ class FileBackedBlob extends (Blob as unknown as { new (): Blob }) implements Bl
621
746
  }
622
747
  return;
623
748
  }
624
- close(fd);
749
+ settled = true;
750
+ closeFd();
625
751
  controller.close();
626
752
  resolve();
627
753
  });
@@ -629,19 +755,26 @@ class FileBackedBlob extends (Blob as unknown as { new (): Blob }) implements Bl
629
755
  buffer = buffer.subarray(0, bytesRead);
630
756
  }
631
757
  if (start !== undefined || end !== undefined) {
758
+ // content offset of the first byte currently in `buffer`. The 8-byte header is only
759
+ // present in — and stripped from — the first read at file position 0; every later read
760
+ // starts HEADER_SIZE into the file relative to its content offset.
761
+ const contentStart = position === 0 ? 0 : position - HEADER_SIZE;
632
762
  if (start && totalContentRead < start) {
633
- // we are before the start of the slice, so we need to read more
634
- position += bytesRead;
763
+ // we are before the start of the slice. Seek straight to it (HEADER_SIZE + start)
764
+ // instead of reading and discarding a 256KB buffer per chunk from byte 0. The header
765
+ // has already been validated and the size detected on the first read (#1457).
766
+ position = HEADER_SIZE + start;
767
+ totalContentRead = start;
635
768
  return readMore(resolve, reject);
636
769
  }
637
770
  if (end && totalContentRead >= end) {
638
771
  // we are past or reached the end of the slice, so we have reached the end, indicate
639
- if (totalContentRead > end) buffer = buffer.subarray(0, end - position);
772
+ if (totalContentRead > end) buffer = buffer.subarray(0, end - contentStart);
640
773
  totalContentRead = size = end;
641
774
  }
642
- if (start && start > position) {
643
- // we need to skip ahead to the start of the slice
644
- buffer = buffer.subarray(start - position);
775
+ if (start && start > contentStart) {
776
+ // we need to skip ahead to the start of the slice within this chunk
777
+ buffer = buffer.subarray(start - contentStart);
645
778
  }
646
779
  }
647
780
  position += bytesRead;
@@ -654,7 +787,8 @@ class FileBackedBlob extends (Blob as unknown as { new (): Blob }) implements Bl
654
787
  return resolve();
655
788
  }
656
789
  if (totalContentRead === size) {
657
- close(fd);
790
+ settled = true;
791
+ closeFd();
658
792
  controller.close();
659
793
  }
660
794
  resolve();
@@ -662,8 +796,10 @@ class FileBackedBlob extends (Blob as unknown as { new (): Blob }) implements Bl
662
796
  });
663
797
  },
664
798
  cancel() {
665
- close(fd);
799
+ cancelled = true;
800
+ closeFd();
666
801
  clearTimeout(timer);
802
+ clearTimeout(openTimer);
667
803
  if (watcher) watcher.close();
668
804
  },
669
805
  });
package/resources/crdt.ts CHANGED
@@ -1,11 +1,18 @@
1
+ // Single definition of the numeric `add` fold, shared by the storage-time merge (crdt.add, via
2
+ // updateAndFreeze) and the read/serialize path (tracked.ts Addition.update). One implementation
3
+ // keeps the two from diverging: a numeric string was concatenated on the storage path but coerced
4
+ // on the read path, and a bigint folded on the storage path but threw (`+bigint`) on the read path.
5
+ export function addValues(previousValue: any, value: any) {
6
+ if (typeof previousValue === 'bigint') return previousValue + BigInt(value);
7
+ if (previousValue == null) return value; // no prior value: the add establishes it
8
+ const previous = +previousValue; // coerce so a numeric string adds instead of concatenating
9
+ if (isNaN(previous)) return value; // non-numeric prior: the add establishes it
10
+ // A number-typed field stays a number even if a stray bigint delta arrives, rather than throwing
11
+ // a number+bigint TypeError on the apply path.
12
+ return previous + (typeof value === 'bigint' ? Number(value) : value);
13
+ }
1
14
  export function add(record, property, action) {
2
- const previousValue = record[property];
3
- if (typeof previousValue === 'bigint') {
4
- record[property] = previousValue + BigInt(action.value);
5
- } else if (isNaN(record[property])) record[property] = action.value;
6
- else {
7
- record[property] = previousValue + action.value;
8
- }
15
+ record[property] = addValues(record[property], action.value);
9
16
  }
10
17
  add.reverse = function (record, property, action) {
11
18
  const previousValue = record[property];
@@ -15,9 +22,16 @@ add.reverse = function (record, property, action) {
15
22
  record[property] = previousValue - action.value;
16
23
  }
17
24
  };
18
- const operations = {
25
+ // The CRDT operation registry. Exported so the storage/apply path (tracked.ts updateAndFreeze)
26
+ // resolves ops against this explicit set rather than the module's export namespace — otherwise a
27
+ // crafted/corrupt `__op__` naming any exported function (addValues, getRecordAtTime, …) would
28
+ // resolve truthy and be invoked with the wrong arguments (throwing and wedging the apply path, or
29
+ // silently corrupting the field). applyReverse/applyForward below already resolve through this.
30
+ // Null-prototype so a crafted `__op__` naming an Object.prototype member (toString, valueOf,
31
+ // constructor, …) resolves to undefined rather than an inherited function.
32
+ export const operations = Object.assign(Object.create(null), {
19
33
  add,
20
- };
34
+ });
21
35
 
22
36
  /**
23
37
  * Rebuild a record update that has a timestamp before the provided newer update
@@ -179,30 +193,22 @@ export function getRecordAtTime(currentEntry, timestamp, store, tableId: number,
179
193
  const boundaryEntry = auditStore.get(auditTime, tableId, recordId);
180
194
  if (boundaryEntry?.type === 'delete') return null;
181
195
  }
182
- // some patches may leave properties in an unknown state, so we need to fill in the blanks
183
- // first we determine if there any unknown properties
184
- // then continue to iterate back through the audit history, filling in the blanks
185
- while (unknowns.size > 0 && auditTime > 0) {
186
- const auditEntry = auditStore.get(auditTime, tableId, recordId);
187
- // The history needed to resolve the remaining unknowns may have been pruned away; stop
188
- // rather than dereferencing a missing entry (mirrors the reverse-walk guard above).
189
- if (!auditEntry) break;
190
- let priorRecord: any;
191
- switch (auditEntry.type) {
192
- case 'put':
193
- priorRecord = auditEntry.getValue(store);
194
- break;
195
- case 'patch':
196
- priorRecord = auditEntry.getValue(store);
197
- break;
198
- }
199
- for (const key in priorRecord) {
200
- if (unknowns.has(key)) {
201
- record[key] = priorRecord[key];
202
- unknowns.delete(key);
196
+ // A reversed patch that set a field to a plain value can't be undone (a plain set has no inverse),
197
+ // so those fields are left "unknown": their value at `timestamp` must come from older history.
198
+ // Reconstruct that state forward from the nearest base so CRDT ops accumulate correctly — e.g. a
199
+ // counter built up by `add` patches and later overwritten by a plain set. The prior code copied
200
+ // the nearest audit entry's raw field, which for a patch is an unresolved `{ __op__ }` object or a
201
+ // single delta rather than the folded value at `timestamp`. If the history needed to reconstruct a
202
+ // key is unavailable (pruned), the key keeps its live value (best effort, as before).
203
+ if (unknowns.size > 0 && auditTime > 0) {
204
+ const priorRecord = reconstructForward(auditStore, store, tableId, recordId, auditTime, timestamp);
205
+ if (priorRecord) {
206
+ for (const key of unknowns) {
207
+ // Object.hasOwn, not `in`: an unknown field named like a prototype member (toString,
208
+ // constructor, …) must not be filled from priorRecord's prototype chain.
209
+ if (Object.hasOwn(priorRecord, key)) record[key] = priorRecord[key];
203
210
  }
204
211
  }
205
- auditTime = auditEntry.previousVersion;
206
212
  }
207
213
  // finally return the record in the state it was at the requested timestamp
208
214
  return record;