@harperfast/harper 5.2.13 → 5.3.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 (655) hide show
  1. package/agent/mcpTools.ts +1 -1
  2. package/agent/session.ts +25 -14
  3. package/bin/cliOperations.ts +58 -9
  4. package/bin/copyDb.ts +282 -59
  5. package/bin/deploySetup.ts +16 -5
  6. package/bin/harper.ts +1 -1
  7. package/bin/help.ts +4 -1
  8. package/bin/lite.ts +4 -1
  9. package/bin/restart.ts +120 -4
  10. package/bin/run.ts +6 -11
  11. package/bin/upgrade.js +7 -3
  12. package/bin/workloadIdentity.ts +119 -0
  13. package/components/Application.ts +3436 -242
  14. package/components/ApplicationScope.ts +8 -0
  15. package/components/EntryHandler.ts +59 -39
  16. package/components/OptionsWatcher.ts +440 -98
  17. package/components/RuntimeModuleTracker.ts +38 -7
  18. package/components/Scope.ts +56 -15
  19. package/components/awaitRestart.ts +84 -0
  20. package/components/componentLoader.ts +381 -32
  21. package/components/componentPreparationLock.ts +16 -5
  22. package/components/deploymentOperations.ts +4 -1
  23. package/components/deploymentRecorder.ts +9 -2
  24. package/components/mcp/adapters/harperHttp.ts +4 -0
  25. package/components/mcp/listChanged.ts +4 -0
  26. package/components/mcp/toolRegistry.ts +2 -0
  27. package/components/mcp/tools/operations.ts +9 -0
  28. package/components/mcp/tools/schemas/operationDescriptions.ts +2 -2
  29. package/components/operations.js +537 -113
  30. package/components/operationsValidation.js +98 -3
  31. package/components/packageComponent.ts +25 -1
  32. package/components/requestRestart.ts +11 -0
  33. package/components/status/ComponentStatusRegistry.ts +59 -0
  34. package/config/RootConfigWatcher.ts +240 -40
  35. package/config/configReadRetry.ts +62 -0
  36. package/config/configUtils.ts +357 -48
  37. package/config/harperConfigEnvVars.ts +170 -27
  38. package/config/parseConfigFile.ts +34 -0
  39. package/config/readConfigFileSync.ts +44 -0
  40. package/config/watcherArming.ts +59 -0
  41. package/config-root.schema.json +33 -0
  42. package/dataLayer/blobBackup.ts +160 -50
  43. package/dataLayer/delete.ts +6 -1
  44. package/dataLayer/harperBridge/ResourceBridge.ts +80 -10
  45. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
  46. package/dataLayer/hdbInfoController.ts +34 -1
  47. package/dataLayer/insert.ts +44 -1
  48. package/dataLayer/rocksdbBackup.ts +53 -10
  49. package/dataLayer/schema.ts +11 -1
  50. package/dataLayer/schemaDescribe.ts +8 -1
  51. package/dist/agent/mcpTools.js +1 -1
  52. package/dist/agent/mcpTools.js.map +1 -1
  53. package/dist/agent/session.d.ts +22 -0
  54. package/dist/agent/session.js +26 -15
  55. package/dist/agent/session.js.map +1 -1
  56. package/dist/bin/cliOperations.js +61 -9
  57. package/dist/bin/cliOperations.js.map +1 -1
  58. package/dist/bin/copyDb.d.ts +12 -1
  59. package/dist/bin/copyDb.js +248 -60
  60. package/dist/bin/copyDb.js.map +1 -1
  61. package/dist/bin/deploySetup.d.ts +2 -0
  62. package/dist/bin/deploySetup.js +11 -3
  63. package/dist/bin/deploySetup.js.map +1 -1
  64. package/dist/bin/harper.js +1 -1
  65. package/dist/bin/harper.js.map +1 -1
  66. package/dist/bin/help.js +4 -1
  67. package/dist/bin/help.js.map +1 -1
  68. package/dist/bin/lite.js +4 -1
  69. package/dist/bin/lite.js.map +1 -1
  70. package/dist/bin/restart.js +91 -6
  71. package/dist/bin/restart.js.map +1 -1
  72. package/dist/bin/run.js +4 -10
  73. package/dist/bin/run.js.map +1 -1
  74. package/dist/bin/upgrade.js +4 -3
  75. package/dist/bin/upgrade.js.map +1 -1
  76. package/dist/bin/workloadIdentity.d.ts +18 -0
  77. package/dist/bin/workloadIdentity.js +100 -0
  78. package/dist/bin/workloadIdentity.js.map +1 -0
  79. package/dist/components/Application.d.ts +235 -17
  80. package/dist/components/Application.js +3038 -238
  81. package/dist/components/Application.js.map +1 -1
  82. package/dist/components/ApplicationScope.d.ts +8 -0
  83. package/dist/components/ApplicationScope.js +7 -0
  84. package/dist/components/ApplicationScope.js.map +1 -1
  85. package/dist/components/EntryHandler.js +26 -10
  86. package/dist/components/EntryHandler.js.map +1 -1
  87. package/dist/components/OptionsWatcher.d.ts +4 -0
  88. package/dist/components/OptionsWatcher.js +440 -99
  89. package/dist/components/OptionsWatcher.js.map +1 -1
  90. package/dist/components/RuntimeModuleTracker.js +40 -6
  91. package/dist/components/RuntimeModuleTracker.js.map +1 -1
  92. package/dist/components/Scope.js +52 -13
  93. package/dist/components/Scope.js.map +1 -1
  94. package/dist/components/awaitRestart.d.ts +33 -0
  95. package/dist/components/awaitRestart.js +61 -0
  96. package/dist/components/awaitRestart.js.map +1 -0
  97. package/dist/components/componentLoader.d.ts +38 -1
  98. package/dist/components/componentLoader.js +313 -24
  99. package/dist/components/componentLoader.js.map +1 -1
  100. package/dist/components/componentPreparationLock.d.ts +5 -0
  101. package/dist/components/componentPreparationLock.js +14 -6
  102. package/dist/components/componentPreparationLock.js.map +1 -1
  103. package/dist/components/deploymentOperations.js +4 -1
  104. package/dist/components/deploymentOperations.js.map +1 -1
  105. package/dist/components/deploymentRecorder.d.ts +4 -2
  106. package/dist/components/deploymentRecorder.js +1 -0
  107. package/dist/components/deploymentRecorder.js.map +1 -1
  108. package/dist/components/mcp/adapters/harperHttp.js +4 -0
  109. package/dist/components/mcp/adapters/harperHttp.js.map +1 -1
  110. package/dist/components/mcp/listChanged.js +5 -0
  111. package/dist/components/mcp/listChanged.js.map +1 -1
  112. package/dist/components/mcp/toolRegistry.d.ts +1 -0
  113. package/dist/components/mcp/toolRegistry.js.map +1 -1
  114. package/dist/components/mcp/tools/operations.d.ts +5 -0
  115. package/dist/components/mcp/tools/operations.js +9 -0
  116. package/dist/components/mcp/tools/operations.js.map +1 -1
  117. package/dist/components/mcp/tools/schemas/operationDescriptions.js +2 -2
  118. package/dist/components/mcp/tools/schemas/operationDescriptions.js.map +1 -1
  119. package/dist/components/operations.d.ts +28 -0
  120. package/dist/components/operations.js +476 -113
  121. package/dist/components/operations.js.map +1 -1
  122. package/dist/components/operationsValidation.js +97 -3
  123. package/dist/components/operationsValidation.js.map +1 -1
  124. package/dist/components/packageComponent.js +24 -0
  125. package/dist/components/packageComponent.js.map +1 -1
  126. package/dist/components/requestRestart.d.ts +1 -0
  127. package/dist/components/requestRestart.js +7 -0
  128. package/dist/components/requestRestart.js.map +1 -1
  129. package/dist/components/status/ComponentStatusRegistry.d.ts +0 -4
  130. package/dist/components/status/ComponentStatusRegistry.js +63 -0
  131. package/dist/components/status/ComponentStatusRegistry.js.map +1 -1
  132. package/dist/config/RootConfigWatcher.d.ts +9 -1
  133. package/dist/config/RootConfigWatcher.js +228 -37
  134. package/dist/config/RootConfigWatcher.js.map +1 -1
  135. package/dist/config/configReadRetry.d.ts +8 -0
  136. package/dist/config/configReadRetry.js +62 -0
  137. package/dist/config/configReadRetry.js.map +1 -0
  138. package/dist/config/configUtils.d.ts +11 -2
  139. package/dist/config/configUtils.js +304 -47
  140. package/dist/config/configUtils.js.map +1 -1
  141. package/dist/config/harperConfigEnvVars.d.ts +16 -0
  142. package/dist/config/harperConfigEnvVars.js +162 -25
  143. package/dist/config/harperConfigEnvVars.js.map +1 -1
  144. package/dist/config/parseConfigFile.d.ts +4 -0
  145. package/dist/config/parseConfigFile.js +35 -0
  146. package/dist/config/parseConfigFile.js.map +1 -0
  147. package/dist/config/readConfigFileSync.d.ts +1 -0
  148. package/dist/config/readConfigFileSync.js +47 -0
  149. package/dist/config/readConfigFileSync.js.map +1 -0
  150. package/dist/config/watcherArming.d.ts +15 -0
  151. package/dist/config/watcherArming.js +59 -0
  152. package/dist/config/watcherArming.js.map +1 -0
  153. package/dist/dataLayer/blobBackup.d.ts +49 -20
  154. package/dist/dataLayer/blobBackup.js +139 -50
  155. package/dist/dataLayer/blobBackup.js.map +1 -1
  156. package/dist/dataLayer/delete.js +1 -1
  157. package/dist/dataLayer/delete.js.map +1 -1
  158. package/dist/dataLayer/harperBridge/ResourceBridge.d.ts +14 -1
  159. package/dist/dataLayer/harperBridge/ResourceBridge.js +72 -12
  160. package/dist/dataLayer/harperBridge/ResourceBridge.js.map +1 -1
  161. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.d.ts +3 -1
  162. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
  163. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js.map +1 -1
  164. package/dist/dataLayer/hdbInfoController.d.ts +10 -0
  165. package/dist/dataLayer/hdbInfoController.js +30 -1
  166. package/dist/dataLayer/hdbInfoController.js.map +1 -1
  167. package/dist/dataLayer/insert.d.ts +9 -1
  168. package/dist/dataLayer/insert.js +30 -0
  169. package/dist/dataLayer/insert.js.map +1 -1
  170. package/dist/dataLayer/rocksdbBackup.d.ts +2 -2
  171. package/dist/dataLayer/rocksdbBackup.js +45 -8
  172. package/dist/dataLayer/rocksdbBackup.js.map +1 -1
  173. package/dist/dataLayer/schema.js +8 -0
  174. package/dist/dataLayer/schema.js.map +1 -1
  175. package/dist/dataLayer/schemaDescribe.js +8 -1
  176. package/dist/dataLayer/schemaDescribe.js.map +1 -1
  177. package/dist/index.d.ts +2 -1
  178. package/dist/index.js +4 -1
  179. package/dist/index.js.map +1 -1
  180. package/dist/json/systemSchema.json +55 -0
  181. package/dist/resources/DatabaseTransaction.d.ts +77 -0
  182. package/dist/resources/DatabaseTransaction.js +586 -54
  183. package/dist/resources/DatabaseTransaction.js.map +1 -1
  184. package/dist/resources/LMDBTransaction.d.ts +2 -1
  185. package/dist/resources/LMDBTransaction.js +43 -6
  186. package/dist/resources/LMDBTransaction.js.map +1 -1
  187. package/dist/resources/PrimaryRocksDatabase.d.ts +1 -0
  188. package/dist/resources/PrimaryRocksDatabase.js +49 -5
  189. package/dist/resources/PrimaryRocksDatabase.js.map +1 -1
  190. package/dist/resources/RecordEncoder.d.ts +20 -0
  191. package/dist/resources/RecordEncoder.js +110 -9
  192. package/dist/resources/RecordEncoder.js.map +1 -1
  193. package/dist/resources/RequestTarget.d.ts +2 -0
  194. package/dist/resources/RequestTarget.js.map +1 -1
  195. package/dist/resources/Resource.js +117 -24
  196. package/dist/resources/Resource.js.map +1 -1
  197. package/dist/resources/ResourceInterface.d.ts +28 -1
  198. package/dist/resources/ResourceInterface.js.map +1 -1
  199. package/dist/resources/RocksIndexStore.d.ts +6 -1
  200. package/dist/resources/RocksIndexStore.js +24 -9
  201. package/dist/resources/RocksIndexStore.js.map +1 -1
  202. package/dist/resources/RocksTransactionLogStore.d.ts +24 -1
  203. package/dist/resources/RocksTransactionLogStore.js +160 -49
  204. package/dist/resources/RocksTransactionLogStore.js.map +1 -1
  205. package/dist/resources/Table.d.ts +165 -10
  206. package/dist/resources/Table.js +1805 -303
  207. package/dist/resources/Table.js.map +1 -1
  208. package/dist/resources/analytics/write.js +10 -3
  209. package/dist/resources/analytics/write.js.map +1 -1
  210. package/dist/resources/auditStore.d.ts +181 -2
  211. package/dist/resources/auditStore.js +640 -29
  212. package/dist/resources/auditStore.js.map +1 -1
  213. package/dist/resources/blob.d.ts +129 -9
  214. package/dist/resources/blob.js +992 -114
  215. package/dist/resources/blob.js.map +1 -1
  216. package/dist/resources/branchDatabase.d.ts +48 -0
  217. package/dist/resources/branchDatabase.js +892 -0
  218. package/dist/resources/branchDatabase.js.map +1 -0
  219. package/dist/resources/crdt.js +50 -12
  220. package/dist/resources/crdt.js.map +1 -1
  221. package/dist/resources/dataLoader.js +3 -4
  222. package/dist/resources/dataLoader.js.map +1 -1
  223. package/dist/resources/databases.d.ts +157 -14
  224. package/dist/resources/databases.js +1462 -325
  225. package/dist/resources/databases.js.map +1 -1
  226. package/dist/resources/defineTable.d.ts +10 -2
  227. package/dist/resources/defineTable.js +9 -1
  228. package/dist/resources/defineTable.js.map +1 -1
  229. package/dist/resources/derivedIndexRegistry.d.ts +5 -0
  230. package/dist/resources/derivedIndexRegistry.js +68 -0
  231. package/dist/resources/derivedIndexRegistry.js.map +1 -0
  232. package/dist/resources/derivedIndexRuntime.d.ts +215 -0
  233. package/dist/resources/derivedIndexRuntime.js +2027 -0
  234. package/dist/resources/derivedIndexRuntime.js.map +1 -0
  235. package/dist/resources/graphql.d.ts +1 -1
  236. package/dist/resources/graphql.js +52 -16
  237. package/dist/resources/graphql.js.map +1 -1
  238. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +103 -9
  239. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +854 -41
  240. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
  241. package/dist/resources/indexes/hnswDerivedIndex.d.ts +67 -0
  242. package/dist/resources/indexes/hnswDerivedIndex.js +464 -0
  243. package/dist/resources/indexes/hnswDerivedIndex.js.map +1 -0
  244. package/dist/resources/indexes/hnswPlaneBinding.d.ts +65 -0
  245. package/dist/resources/indexes/hnswPlaneBinding.js +91 -0
  246. package/dist/resources/indexes/hnswPlaneBinding.js.map +1 -0
  247. package/dist/resources/longLivedTransactions.d.ts +71 -0
  248. package/dist/resources/longLivedTransactions.js +358 -0
  249. package/dist/resources/longLivedTransactions.js.map +1 -0
  250. package/dist/resources/models/backendRegistry.d.ts +26 -0
  251. package/dist/resources/models/backendRegistry.js +60 -2
  252. package/dist/resources/models/backendRegistry.js.map +1 -1
  253. package/dist/resources/models/bootstrap.d.ts +33 -1
  254. package/dist/resources/models/bootstrap.js +416 -31
  255. package/dist/resources/models/bootstrap.js.map +1 -1
  256. package/dist/resources/nodeIdMapping.d.ts +5 -0
  257. package/dist/resources/nodeIdMapping.js +49 -0
  258. package/dist/resources/nodeIdMapping.js.map +1 -1
  259. package/dist/resources/recordLock.d.ts +123 -0
  260. package/dist/resources/recordLock.js +315 -0
  261. package/dist/resources/recordLock.js.map +1 -0
  262. package/dist/resources/recordLockCoordinator.d.ts +557 -0
  263. package/dist/resources/recordLockCoordinator.js +2565 -0
  264. package/dist/resources/recordLockCoordinator.js.map +1 -0
  265. package/dist/resources/replayLogs.d.ts +14 -1
  266. package/dist/resources/replayLogs.js +157 -24
  267. package/dist/resources/replayLogs.js.map +1 -1
  268. package/dist/resources/replayLogsGuards.d.ts +94 -7
  269. package/dist/resources/replayLogsGuards.js +111 -7
  270. package/dist/resources/replayLogsGuards.js.map +1 -1
  271. package/dist/resources/replicatedApplyFailure.d.ts +16 -0
  272. package/dist/resources/replicatedApplyFailure.js +63 -0
  273. package/dist/resources/replicatedApplyFailure.js.map +1 -0
  274. package/dist/resources/scheduler/scheduler.js +3 -3
  275. package/dist/resources/scheduler/scheduler.js.map +1 -1
  276. package/dist/resources/search.d.ts +10 -4
  277. package/dist/resources/search.js +283 -37
  278. package/dist/resources/search.js.map +1 -1
  279. package/dist/resources/tracked.d.ts +5 -1
  280. package/dist/resources/tracked.js +74 -23
  281. package/dist/resources/tracked.js.map +1 -1
  282. package/dist/resources/transactionBroadcast.d.ts +1 -1
  283. package/dist/resources/transactionBroadcast.js +2 -2
  284. package/dist/resources/transactionBroadcast.js.map +1 -1
  285. package/dist/security/auth.js +61 -30
  286. package/dist/security/auth.js.map +1 -1
  287. package/dist/security/authn/oidc/claims.d.ts +22 -0
  288. package/dist/security/authn/oidc/claims.js +71 -0
  289. package/dist/security/authn/oidc/claims.js.map +1 -0
  290. package/dist/security/authn/oidc/identityToken.d.ts +27 -0
  291. package/dist/security/authn/oidc/identityToken.js +111 -0
  292. package/dist/security/authn/oidc/identityToken.js.map +1 -0
  293. package/dist/security/authn/oidc/jwks.d.ts +25 -0
  294. package/dist/security/authn/oidc/jwks.js +261 -0
  295. package/dist/security/authn/oidc/jwks.js.map +1 -0
  296. package/dist/security/authn/oidc/providers/generic.d.ts +13 -0
  297. package/dist/security/authn/oidc/providers/generic.js +34 -0
  298. package/dist/security/authn/oidc/providers/generic.js.map +1 -0
  299. package/dist/security/authn/oidc/providers/githubActions.d.ts +11 -0
  300. package/dist/security/authn/oidc/providers/githubActions.js +129 -0
  301. package/dist/security/authn/oidc/providers/githubActions.js.map +1 -0
  302. package/dist/security/authn/oidc/providers/index.d.ts +37 -0
  303. package/dist/security/authn/oidc/providers/index.js +24 -0
  304. package/dist/security/authn/oidc/providers/index.js.map +1 -0
  305. package/dist/security/authn/oidc/tokenExchange.d.ts +12 -0
  306. package/dist/security/authn/oidc/tokenExchange.js +306 -0
  307. package/dist/security/authn/oidc/tokenExchange.js.map +1 -0
  308. package/dist/security/authn/oidc/trustPolicyOperations.d.ts +49 -0
  309. package/dist/security/authn/oidc/trustPolicyOperations.js +358 -0
  310. package/dist/security/authn/oidc/trustPolicyOperations.js.map +1 -0
  311. package/dist/security/authn/oidc/types.d.ts +38 -0
  312. package/dist/security/authn/oidc/types.js +6 -0
  313. package/dist/security/authn/oidc/types.js.map +1 -0
  314. package/dist/security/certificateVerification/index.js +40 -11
  315. package/dist/security/certificateVerification/index.js.map +1 -1
  316. package/dist/security/certificateVerification/trustedIssuers.d.ts +24 -0
  317. package/dist/security/certificateVerification/trustedIssuers.js +79 -0
  318. package/dist/security/certificateVerification/trustedIssuers.js.map +1 -0
  319. package/dist/security/certificateVerification/types.d.ts +1 -0
  320. package/dist/security/credentialProvenance.d.ts +35 -0
  321. package/dist/security/credentialProvenance.js +51 -0
  322. package/dist/security/credentialProvenance.js.map +1 -0
  323. package/dist/security/credentialRejection.d.ts +4 -0
  324. package/dist/security/credentialRejection.js +24 -0
  325. package/dist/security/credentialRejection.js.map +1 -0
  326. package/dist/security/deferredAuthentication.d.ts +36 -0
  327. package/dist/security/deferredAuthentication.js +70 -0
  328. package/dist/security/deferredAuthentication.js.map +1 -0
  329. package/dist/security/impersonation.d.ts +21 -0
  330. package/dist/security/impersonation.js +108 -9
  331. package/dist/security/impersonation.js.map +1 -1
  332. package/dist/security/jsLoader.d.ts +6 -0
  333. package/dist/security/jsLoader.js +77 -15
  334. package/dist/security/jsLoader.js.map +1 -1
  335. package/dist/security/keys.js +301 -71
  336. package/dist/security/keys.js.map +1 -1
  337. package/dist/security/operationScope.d.ts +21 -0
  338. package/dist/security/operationScope.js +36 -0
  339. package/dist/security/operationScope.js.map +1 -0
  340. package/dist/security/permissionsTranslator.js +21 -0
  341. package/dist/security/permissionsTranslator.js.map +1 -1
  342. package/dist/security/tokenAuthentication.d.ts +19 -1
  343. package/dist/security/tokenAuthentication.js +191 -10
  344. package/dist/security/tokenAuthentication.js.map +1 -1
  345. package/dist/security/user.js +4 -3
  346. package/dist/security/user.js.map +1 -1
  347. package/dist/server/DurableSubscriptionsSession.d.ts +2 -2
  348. package/dist/server/DurableSubscriptionsSession.js +67 -10
  349. package/dist/server/DurableSubscriptionsSession.js.map +1 -1
  350. package/dist/server/REST.js +106 -2
  351. package/dist/server/REST.js.map +1 -1
  352. package/dist/server/graphqlQuerying.js +4 -0
  353. package/dist/server/graphqlQuerying.js.map +1 -1
  354. package/dist/server/http.d.ts +16 -1
  355. package/dist/server/http.js +122 -17
  356. package/dist/server/http.js.map +1 -1
  357. package/dist/server/itc/serverHandlers.js +8 -1
  358. package/dist/server/itc/serverHandlers.js.map +1 -1
  359. package/dist/server/jobs/jobProcess.js +6 -2
  360. package/dist/server/jobs/jobProcess.js.map +1 -1
  361. package/dist/server/jobs/jobs.js +4 -1
  362. package/dist/server/jobs/jobs.js.map +1 -1
  363. package/dist/server/liveSubscriptionAuth.d.ts +26 -4
  364. package/dist/server/liveSubscriptionAuth.js +105 -39
  365. package/dist/server/liveSubscriptionAuth.js.map +1 -1
  366. package/dist/server/loadRootComponents.js +49 -10
  367. package/dist/server/loadRootComponents.js.map +1 -1
  368. package/dist/server/mqtt.d.ts +2 -0
  369. package/dist/server/mqtt.js +165 -30
  370. package/dist/server/mqtt.js.map +1 -1
  371. package/dist/server/nodeName.d.ts +2 -0
  372. package/dist/server/nodeName.js +107 -23
  373. package/dist/server/nodeName.js.map +1 -1
  374. package/dist/server/serverHelpers/Headers.d.ts +27 -0
  375. package/dist/server/serverHelpers/Headers.js +145 -1
  376. package/dist/server/serverHelpers/Headers.js.map +1 -1
  377. package/dist/server/serverHelpers/NodeAdapterResponse.d.ts +48 -0
  378. package/dist/server/serverHelpers/NodeAdapterResponse.js +220 -0
  379. package/dist/server/serverHelpers/NodeAdapterResponse.js.map +1 -0
  380. package/dist/server/serverHelpers/Request.d.ts +5 -10
  381. package/dist/server/serverHelpers/Request.js +38 -136
  382. package/dist/server/serverHelpers/Request.js.map +1 -1
  383. package/dist/server/serverHelpers/contentTypes.d.ts +11 -0
  384. package/dist/server/serverHelpers/contentTypes.js +221 -40
  385. package/dist/server/serverHelpers/contentTypes.js.map +1 -1
  386. package/dist/server/serverHelpers/deployValidationState.d.ts +3 -0
  387. package/dist/server/serverHelpers/deployValidationState.js +9 -19
  388. package/dist/server/serverHelpers/deployValidationState.js.map +1 -1
  389. package/dist/server/serverHelpers/operationAuthorizationState.d.ts +12 -0
  390. package/dist/server/serverHelpers/operationAuthorizationState.js +24 -2
  391. package/dist/server/serverHelpers/operationAuthorizationState.js.map +1 -1
  392. package/dist/server/serverHelpers/registeredOperations.d.ts +5 -4
  393. package/dist/server/serverHelpers/registeredOperations.js +74 -21
  394. package/dist/server/serverHelpers/registeredOperations.js.map +1 -1
  395. package/dist/server/serverHelpers/requestSanitization.d.ts +11 -0
  396. package/dist/server/serverHelpers/requestSanitization.js +20 -0
  397. package/dist/server/serverHelpers/requestSanitization.js.map +1 -0
  398. package/dist/server/serverHelpers/serverHandlers.js +6 -3
  399. package/dist/server/serverHelpers/serverHandlers.js.map +1 -1
  400. package/dist/server/serverHelpers/serverUtilities.d.ts +18 -0
  401. package/dist/server/serverHelpers/serverUtilities.js +178 -29
  402. package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
  403. package/dist/server/serverHelpers/sharedMessageEncoding.d.ts +67 -0
  404. package/dist/server/serverHelpers/sharedMessageEncoding.js +280 -0
  405. package/dist/server/serverHelpers/sharedMessageEncoding.js.map +1 -0
  406. package/dist/server/serverHelpers/uwsServer.js +19 -1
  407. package/dist/server/serverHelpers/uwsServer.js.map +1 -1
  408. package/dist/server/static.js +24 -28
  409. package/dist/server/static.js.map +1 -1
  410. package/dist/server/storageReclamation.d.ts +5 -0
  411. package/dist/server/storageReclamation.js +17 -1
  412. package/dist/server/storageReclamation.js.map +1 -1
  413. package/dist/server/threads/isolatedApplications.d.ts +47 -0
  414. package/dist/server/threads/isolatedApplications.js +171 -0
  415. package/dist/server/threads/isolatedApplications.js.map +1 -0
  416. package/dist/server/threads/itc.d.ts +7 -2
  417. package/dist/server/threads/itc.js +5 -1
  418. package/dist/server/threads/itc.js.map +1 -1
  419. package/dist/server/threads/logRotationTransport.d.ts +1 -0
  420. package/dist/server/threads/logRotationTransport.js +33 -0
  421. package/dist/server/threads/logRotationTransport.js.map +1 -0
  422. package/dist/server/threads/manageThreads.d.ts +83 -3
  423. package/dist/server/threads/manageThreads.js +769 -75
  424. package/dist/server/threads/manageThreads.js.map +1 -1
  425. package/dist/server/threads/socketRouter.d.ts +1 -0
  426. package/dist/server/threads/socketRouter.js +277 -31
  427. package/dist/server/threads/socketRouter.js.map +1 -1
  428. package/dist/server/threads/threadHeapMemory.d.ts +2 -0
  429. package/dist/server/threads/threadHeapMemory.js +31 -0
  430. package/dist/server/threads/threadHeapMemory.js.map +1 -0
  431. package/dist/server/threads/threadServer.js +76 -22
  432. package/dist/server/threads/threadServer.js.map +1 -1
  433. package/dist/sqlEngine/config.d.ts +1 -3
  434. package/dist/sqlEngine/config.js +19 -16
  435. package/dist/sqlEngine/config.js.map +1 -1
  436. package/dist/sqlTranslator/index.d.ts +1 -1
  437. package/dist/sqlTranslator/index.js +30 -7
  438. package/dist/sqlTranslator/index.js.map +1 -1
  439. package/dist/upgrade/directives/5-3-0.d.ts +7 -0
  440. package/dist/upgrade/directives/5-3-0.js +148 -0
  441. package/dist/upgrade/directives/5-3-0.js.map +1 -0
  442. package/dist/upgrade/directives/directivesController.js +2 -1
  443. package/dist/upgrade/directives/directivesController.js.map +1 -1
  444. package/dist/utility/OperationFunctionCaller.js +2 -1
  445. package/dist/utility/OperationFunctionCaller.js.map +1 -1
  446. package/dist/utility/common_utils.d.ts +16 -0
  447. package/dist/utility/common_utils.js +32 -6
  448. package/dist/utility/common_utils.js.map +1 -1
  449. package/dist/utility/componentNames.d.ts +8 -0
  450. package/dist/utility/componentNames.js +12 -1
  451. package/dist/utility/componentNames.js.map +1 -1
  452. package/dist/utility/environment/environmentManager.js +3 -6
  453. package/dist/utility/environment/environmentManager.js.map +1 -1
  454. package/dist/utility/environment/systemInformation.d.ts +1 -0
  455. package/dist/utility/environment/systemInformation.js +1 -0
  456. package/dist/utility/environment/systemInformation.js.map +1 -1
  457. package/dist/utility/errors/commonErrors.d.ts +2 -0
  458. package/dist/utility/errors/commonErrors.js +2 -0
  459. package/dist/utility/errors/commonErrors.js.map +1 -1
  460. package/dist/utility/errors/hdbError.d.ts +33 -0
  461. package/dist/utility/errors/hdbError.js +58 -1
  462. package/dist/utility/errors/hdbError.js.map +1 -1
  463. package/dist/utility/globalSchema.d.ts +18 -0
  464. package/dist/utility/hdbTerms.d.ts +18 -0
  465. package/dist/utility/hdbTerms.js +20 -2
  466. package/dist/utility/hdbTerms.js.map +1 -1
  467. package/dist/utility/logging/harper_logger.d.ts +2 -0
  468. package/dist/utility/logging/harper_logger.js +286 -30
  469. package/dist/utility/logging/harper_logger.js.map +1 -1
  470. package/dist/utility/logging/logGenerationCoordinator.d.ts +35 -0
  471. package/dist/utility/logging/logGenerationCoordinator.js +184 -0
  472. package/dist/utility/logging/logGenerationCoordinator.js.map +1 -0
  473. package/dist/utility/logging/logRotation.d.ts +46 -0
  474. package/dist/utility/logging/logRotation.js +365 -0
  475. package/dist/utility/logging/logRotation.js.map +1 -0
  476. package/dist/utility/logging/logRotator.d.ts +1 -1
  477. package/dist/utility/logging/logRotator.js +192 -85
  478. package/dist/utility/logging/logRotator.js.map +1 -1
  479. package/dist/utility/nodeIdentity.d.ts +9 -0
  480. package/dist/utility/nodeIdentity.js +58 -0
  481. package/dist/utility/nodeIdentity.js.map +1 -0
  482. package/dist/utility/npmUtilities.js +11 -7
  483. package/dist/utility/npmUtilities.js.map +1 -1
  484. package/dist/utility/operationPermissions.d.ts +3 -1
  485. package/dist/utility/operationPermissions.js +16 -1
  486. package/dist/utility/operationPermissions.js.map +1 -1
  487. package/dist/utility/operation_authorization.d.ts +10 -7
  488. package/dist/utility/operation_authorization.js +212 -41
  489. package/dist/utility/operation_authorization.js.map +1 -1
  490. package/dist/utility/watchPath.d.ts +29 -0
  491. package/dist/utility/watchPath.js +68 -0
  492. package/dist/utility/watchPath.js.map +1 -0
  493. package/dist/utility/watcherFallback.d.ts +41 -0
  494. package/dist/utility/watcherFallback.js +153 -0
  495. package/dist/utility/watcherFallback.js.map +1 -1
  496. package/dist/validation/configValidator.d.ts +12 -0
  497. package/dist/validation/configValidator.js +205 -75
  498. package/dist/validation/configValidator.js.map +1 -1
  499. package/dist/validation/installValidator.js +12 -0
  500. package/dist/validation/installValidator.js.map +1 -1
  501. package/dist/validation/validationWrapper.d.ts +11 -0
  502. package/dist/validation/validationWrapper.js +16 -3
  503. package/dist/validation/validationWrapper.js.map +1 -1
  504. package/index.ts +8 -0
  505. package/json/systemSchema.json +55 -0
  506. package/npm-shrinkwrap.json +286 -194
  507. package/package.json +15 -7
  508. package/resources/DESIGN.md +219 -52
  509. package/resources/DatabaseTransaction.ts +657 -52
  510. package/resources/LMDBTransaction.ts +46 -6
  511. package/resources/PrimaryRocksDatabase.ts +46 -7
  512. package/resources/RecordEncoder.ts +124 -9
  513. package/resources/RequestTarget.ts +2 -0
  514. package/resources/Resource.ts +114 -22
  515. package/resources/ResourceInterface.ts +31 -0
  516. package/resources/RocksIndexStore.ts +30 -9
  517. package/resources/RocksTransactionLogStore.ts +188 -51
  518. package/resources/Table.ts +1960 -301
  519. package/resources/analytics/write.ts +10 -3
  520. package/resources/auditStore.ts +647 -32
  521. package/resources/blob.ts +1029 -110
  522. package/resources/branchDatabase.ts +941 -0
  523. package/resources/crdt.ts +76 -12
  524. package/resources/dataLoader.ts +3 -4
  525. package/resources/databases.ts +1584 -320
  526. package/resources/defineTable.ts +18 -2
  527. package/resources/derivedIndexRegistry.ts +56 -0
  528. package/resources/derivedIndexRuntime.ts +2292 -0
  529. package/resources/graphql.ts +72 -17
  530. package/resources/indexes/HierarchicalNavigableSmallWorld.ts +911 -48
  531. package/resources/indexes/hnswDerivedIndex.ts +531 -0
  532. package/resources/indexes/hnswPlaneBinding.ts +174 -0
  533. package/resources/longLivedTransactions.ts +360 -0
  534. package/resources/models/backendRegistry.ts +84 -2
  535. package/resources/models/bootstrap.ts +473 -28
  536. package/resources/nodeIdMapping.ts +50 -0
  537. package/resources/recordLock.ts +419 -0
  538. package/resources/recordLockCoordinator.ts +3043 -0
  539. package/resources/replayLogs.ts +152 -26
  540. package/resources/replayLogsGuards.ts +171 -8
  541. package/resources/replicatedApplyFailure.ts +77 -0
  542. package/resources/scheduler/scheduler.ts +4 -4
  543. package/resources/search.ts +288 -46
  544. package/resources/tracked.ts +73 -22
  545. package/resources/transactionBroadcast.ts +3 -3
  546. package/security/auth.ts +68 -29
  547. package/security/authn/oidc/claims.ts +72 -0
  548. package/security/authn/oidc/identityToken.ts +129 -0
  549. package/security/authn/oidc/jwks.ts +260 -0
  550. package/security/authn/oidc/providers/generic.ts +40 -0
  551. package/security/authn/oidc/providers/githubActions.ts +137 -0
  552. package/security/authn/oidc/providers/index.ts +52 -0
  553. package/security/authn/oidc/tokenExchange.ts +300 -0
  554. package/security/authn/oidc/trustPolicyOperations.ts +343 -0
  555. package/security/authn/oidc/types.ts +41 -0
  556. package/security/certificateVerification/index.ts +54 -13
  557. package/security/certificateVerification/trustedIssuers.ts +76 -0
  558. package/security/certificateVerification/types.ts +1 -0
  559. package/security/credentialProvenance.ts +47 -0
  560. package/security/credentialRejection.ts +22 -0
  561. package/security/deferredAuthentication.ts +71 -0
  562. package/security/impersonation.ts +117 -12
  563. package/security/jsLoader.ts +83 -18
  564. package/security/keys.ts +298 -72
  565. package/security/operationScope.ts +33 -0
  566. package/security/permissionsTranslator.js +23 -0
  567. package/security/tokenAuthentication.ts +233 -12
  568. package/security/user.ts +4 -3
  569. package/server/DESIGN.md +194 -16
  570. package/server/DurableSubscriptionsSession.ts +71 -11
  571. package/server/REST.ts +115 -4
  572. package/server/graphqlQuerying.ts +4 -0
  573. package/server/http.ts +133 -20
  574. package/server/itc/serverHandlers.js +8 -1
  575. package/server/jobs/jobProcess.ts +8 -2
  576. package/server/jobs/jobs.ts +4 -1
  577. package/server/liveSubscriptionAuth.ts +129 -46
  578. package/server/loadRootComponents.js +50 -8
  579. package/server/mqtt.ts +179 -38
  580. package/server/nodeName.ts +103 -21
  581. package/server/serverHelpers/Headers.ts +135 -0
  582. package/server/serverHelpers/NodeAdapterResponse.ts +221 -0
  583. package/server/serverHelpers/Request.ts +33 -131
  584. package/server/serverHelpers/contentTypes.ts +217 -36
  585. package/server/serverHelpers/deployValidationState.ts +24 -13
  586. package/server/serverHelpers/operationAuthorizationState.ts +34 -3
  587. package/server/serverHelpers/registeredOperations.ts +79 -22
  588. package/server/serverHelpers/requestSanitization.ts +15 -0
  589. package/server/serverHelpers/serverHandlers.js +6 -3
  590. package/server/serverHelpers/serverUtilities.ts +232 -40
  591. package/server/serverHelpers/sharedMessageEncoding.ts +307 -0
  592. package/server/serverHelpers/uwsServer.ts +17 -2
  593. package/server/static.ts +23 -29
  594. package/server/storageReclamation.ts +15 -2
  595. package/server/threads/isolatedApplications.ts +157 -0
  596. package/server/threads/itc.js +11 -1
  597. package/server/threads/logRotationTransport.ts +40 -0
  598. package/server/threads/manageThreads.js +771 -66
  599. package/server/threads/socketRouter.ts +291 -30
  600. package/server/threads/threadHeapMemory.ts +26 -0
  601. package/server/threads/threadServer.js +73 -22
  602. package/sqlTranslator/index.ts +31 -8
  603. package/studio/web/assets/{Chat-4RrB5134.js → Chat-D3j-1yY1.js} +1 -1
  604. package/studio/web/assets/{FloatingChat-omlNMDcJ.js → FloatingChat-BxJGYcfB.js} +3 -3
  605. package/studio/web/assets/{apiToken-Bke3wvfZ.js → apiToken-CT55oWOe.js} +1 -1
  606. package/studio/web/assets/{applications-DvFDYJgK.js → applications-D9Ct9_vm.js} +1 -1
  607. package/studio/web/assets/{cssMode-C1vRa7zh.js → cssMode-DV8H7VwA.js} +1 -1
  608. package/studio/web/assets/{editor-3XRWEDWX.js → editor-uatc0unt.js} +1 -1
  609. package/studio/web/assets/{html-CTY5tdMr.js → html-Bm6D6paN.js} +1 -1
  610. package/studio/web/assets/{htmlMode-CG1vSD9t.js → htmlMode-CEn7tpLG.js} +1 -1
  611. package/studio/web/assets/{index-Dfpeofdu.js → index-BIXW6Pu4.js} +5 -5
  612. package/studio/web/assets/{index.lazy-B1VOIv-t.js → index.lazy-UI7L-Vrk.js} +1 -1
  613. package/studio/web/assets/{javascript-CJeJzGnI.js → javascript-CJ0G3AFZ.js} +1 -1
  614. package/studio/web/assets/{jsonMode-CYPBwM82.js → jsonMode-DQADAYEa.js} +1 -1
  615. package/studio/web/assets/{languageServices-IKH4GUHl.js → languageServices-CAQJXWcI.js} +1 -1
  616. package/studio/web/assets/{lspLanguageFeatures-BC8_gxKG.js → lspLanguageFeatures-CCQ8P5sY.js} +1 -1
  617. package/studio/web/assets/{notifications-BfKBpYcq.js → notifications-BbxTU6Aw.js} +1 -1
  618. package/studio/web/assets/{notifications-DFbArTfC.js → notifications-Cvb3P1lB.js} +1 -1
  619. package/studio/web/assets/{profile-Q4-T6c-S.js → profile-Yyb7gsvL.js} +1 -1
  620. package/studio/web/assets/{regions-CtkV0xje.js → regions-OgjGHlU5.js} +1 -1
  621. package/studio/web/assets/{register-1ZZuMsiA.js → register-6qwNEOY3.js} +2 -2
  622. package/studio/web/assets/{setComponentFile-ZWLcWv5X.js → setComponentFile-BilDMtgB.js} +1 -1
  623. package/studio/web/assets/{setup-DWprJyJy.js → setup-J6qJ7OIU.js} +2 -2
  624. package/studio/web/assets/{status--aNm8isn.js → status-0RWGcfyD.js} +1 -1
  625. package/studio/web/assets/{toggleHighContrast-Cq_lt3XD.js → toggleHighContrast-BIn-vErT.js} +1 -1
  626. package/studio/web/assets/{tsMode-pjgytARx.js → tsMode-DgUXku4d.js} +1 -1
  627. package/studio/web/assets/{typescript-Cdg0mqUh.js → typescript-C9orXcsM.js} +1 -1
  628. package/studio/web/assets/{useEntityRestURL-RZhaY8Rn.js → useEntityRestURL-BEoXXbUB.js} +1 -1
  629. package/studio/web/assets/{workers-BgoXIqQe.js → workers-JVzSDmgx.js} +1 -1
  630. package/studio/web/assets/{xml-BwSeDMiP.js → xml-Cq-S8S4X.js} +1 -1
  631. package/studio/web/assets/{yaml-DotCUG5l.js → yaml-sfoRdh1M.js} +1 -1
  632. package/studio/web/index.html +1 -1
  633. package/upgrade/directives/5-3-0.ts +132 -0
  634. package/upgrade/directives/directivesController.ts +2 -1
  635. package/utility/OperationFunctionCaller.ts +2 -1
  636. package/utility/common_utils.ts +30 -5
  637. package/utility/componentNames.ts +12 -0
  638. package/utility/environment/environmentManager.ts +3 -7
  639. package/utility/environment/systemInformation.ts +7 -0
  640. package/utility/errors/commonErrors.ts +4 -0
  641. package/utility/errors/hdbError.ts +57 -0
  642. package/utility/hdbTerms.ts +19 -0
  643. package/utility/logging/harper_logger.ts +278 -26
  644. package/utility/logging/logGenerationCoordinator.ts +196 -0
  645. package/utility/logging/logRotation.ts +367 -0
  646. package/utility/logging/logRotator.ts +213 -81
  647. package/utility/nodeIdentity.ts +45 -0
  648. package/utility/npmUtilities.ts +12 -8
  649. package/utility/operationPermissions.ts +18 -1
  650. package/utility/operation_authorization.ts +231 -42
  651. package/utility/watchPath.ts +63 -0
  652. package/utility/watcherFallback.ts +148 -0
  653. package/validation/configValidator.ts +215 -75
  654. package/validation/installValidator.ts +15 -0
  655. package/validation/validationWrapper.ts +18 -4
@@ -1,10 +1,6 @@
1
1
  'use strict';
2
2
 
3
- import { promises as fsProm, createReadStream, createWriteStream, mkdirSync } from 'fs';
4
- import { createGzip } from 'zlib';
5
- import { promisify } from 'util';
6
- import { pipeline } from 'stream';
7
- const pipe = promisify(pipeline);
3
+ import { existsSync, mkdirSync, statSync, promises as fsProm } from 'fs';
8
4
  import * as path from 'path';
9
5
  import * as envMgr from '../environment/environmentManager.ts';
10
6
  envMgr.initSync();
@@ -12,9 +8,21 @@ import hdbLogger from './harper_logger.ts';
12
8
  import { CONFIG_PARAMS } from '../hdbTerms.ts';
13
9
  import { convertToMS } from '../common_utils.ts';
14
10
  import { onStorageReclamation } from '../../server/storageReclamation.ts';
11
+ import { requestStaleDescriptorRelease } from './logGenerationCoordinator.ts';
12
+ import {
13
+ compressPendingArchives,
14
+ INVALID_MAX_SIZE_MSG,
15
+ isArchivePendingQuiescence,
16
+ parseMaxSize,
17
+ publishArchivedGeneration,
18
+ resolveRotatedLogDir,
19
+ retryPendingGenerations,
20
+ rotateLogFileSync,
21
+ } from './logRotation.ts';
15
22
 
16
23
  // Interval in ms to check log file and decide if it should be rotated.
17
24
  const LOG_AUDIT_INTERVAL = 60000;
25
+ const RELEASE_PROOF_REPORT_INTERVAL = 5 * 60 * 1000;
18
26
  const INT_SIZE_UNDEFINED_MSG =
19
27
  "'interval' and 'maxSize' are both undefined, to enable logging rotation at least one of these values must be defined in harperdb-config.yaml";
20
28
 
@@ -26,7 +34,16 @@ export { logRotator };
26
34
  * If log file is within the values set in config, log file will be renamed/moved and a new empty hdb.log created.
27
35
  * @returns LogRotator
28
36
  */
29
- function logRotator({ logger, maxSize, interval, retention, enabled, path: rotatedLogDir, auditInterval }: any) {
37
+ function logRotator({
38
+ logger,
39
+ maxSize,
40
+ interval,
41
+ retention,
42
+ enabled,
43
+ compress,
44
+ path: rotatedLogDir,
45
+ auditInterval,
46
+ }: any) {
30
47
  if (enabled === false) return;
31
48
  let reclamationPriority = 0;
32
49
  onStorageReclamation(
@@ -41,21 +58,18 @@ function logRotator({ logger, maxSize, interval, retention, enabled, path: rotat
41
58
  throw new Error(INT_SIZE_UNDEFINED_MSG);
42
59
  }
43
60
 
44
- if (!rotatedLogDir) {
45
- rotatedLogDir = path.join(path.dirname(logger.path), 'rotated');
46
- }
61
+ rotatedLogDir = resolveRotatedLogDir(logger.path, rotatedLogDir);
47
62
  mkdirSync(rotatedLogDir, { recursive: true });
48
63
 
49
- // Convert maxSize param to bytes.
50
- let maxBytes;
51
- if (maxSize) {
52
- const unit = maxSize.slice(-1);
53
- const size = maxSize.slice(0, -1);
54
- if (unit === 'G') maxBytes = size * 1000000000;
55
- else if (unit === 'M') maxBytes = size * 1000000;
56
- else maxBytes = size * 1000;
64
+ const maxBytes = parseMaxSize(maxSize);
65
+ if (maxSize && !maxBytes) {
66
+ hdbLogger.error(`Ignoring logging.rotation.maxSize '${maxSize}': ${INVALID_MAX_SIZE_MSG}`);
57
67
  }
58
68
 
69
+ // The rotation block first, because that is all the write-path guard can read — environmentManager
70
+ // imports harper_logger — and two sources would mean two destruction policies for one log.
71
+ const compressArchives = compress ?? envMgr.get(CONFIG_PARAMS.LOGGING_ROTATION_COMPRESS);
72
+
59
73
  // Convert interval param to ms.
60
74
  let maxInterval;
61
75
  if (interval) {
@@ -63,101 +77,219 @@ function logRotator({ logger, maxSize, interval, retention, enabled, path: rotat
63
77
  }
64
78
 
65
79
  let lastRotatedLogPath;
66
- // convert date.now to minutes
67
80
  let lastRotationTime = Date.now();
81
+ let observedGeneration;
82
+ try {
83
+ const active = statSync(logger.path);
84
+ observedGeneration = generationIdentity(active);
85
+ if (active.birthtimeMs > 0) lastRotationTime = Math.min(lastRotationTime, active.birthtimeMs);
86
+ } catch {}
68
87
  hdbLogger.trace('Log rotate enabled, maxSize:', maxSize, 'interval:', interval);
88
+ let tickInFlight = false;
89
+ let ended = false;
90
+ let releaseProofStalled = false;
91
+ let nextReleaseProofReport = 0;
92
+ let retentionCursor = 0;
93
+ const auditIntervalMs = auditInterval ?? LOG_AUDIT_INTERVAL;
94
+ const compressionBudgetMs = Math.max(1, Math.floor(auditIntervalMs / 4));
95
+ /**
96
+ * rename() reports ENOENT for a missing destination directory as well as a missing source, and
97
+ * only the second is the benign lost race. The directory is created once at rotator start, so a
98
+ * rotation target removed under a running instance otherwise stops rotation permanently and
99
+ * silently — and with `interval` and no `maxSize` there is no write-path guard to recreate it.
100
+ */
101
+ function recoverRotationTarget(err: any) {
102
+ if (err.code !== 'ENOENT' || existsSync(rotatedLogDir)) return;
103
+ try {
104
+ mkdirSync(rotatedLogDir, { recursive: true });
105
+ hdbLogger.warn(`The log rotation directory ${rotatedLogDir} was missing and has been recreated`);
106
+ } catch (mkdirErr) {
107
+ hdbLogger.error('Could not recreate the log rotation directory', rotatedLogDir, mkdirErr);
108
+ }
109
+ }
69
110
  const setIntervalId = setInterval(async () => {
70
- // A missing/relocated active log file only invalidates the rotation checks below — retention cleanup
71
- // must still run. So skip the individual check on ENOENT rather than returning from the whole tick.
72
- if (maxBytes) {
73
- let fileStats;
74
- try {
75
- fileStats = await fsProm.stat(logger.path);
76
- } catch (err) {
77
- // If the log file doesn't exist, skip the size-based rotation check
78
- if (err.code !== 'ENOENT') throw err;
79
- }
80
-
81
- if (fileStats && fileStats.size >= maxBytes) {
111
+ // setInterval does not await the callback, and one pass can now wait on peers; overlapping
112
+ // passes would work the same archive twice and double-compress it.
113
+ if (tickInFlight || ended) return;
114
+ tickInFlight = true;
115
+ const tickDeadline = Date.now() + auditIntervalMs;
116
+ // The tick is async but setInterval doesn't await it, so any error that escapes this callback
117
+ // becomes an unhandled rejection rather than surfacing anywhere useful — and since it isn't
118
+ // caught, it also skips the retention cleanup below. Contain everything here and report via
119
+ // the logger instead, so one bad tick (e.g. an unexpected fs error) never kills rotation for
120
+ // the rest of the process's life.
121
+ try {
122
+ if (maxBytes) {
82
123
  try {
83
- lastRotatedLogPath = await moveLogFile(logger.path, rotatedLogDir, logger);
124
+ // statSync, and the rename in the same turn: an await here lets a writing thread rotate
125
+ // the generation this tick measured and start a fresh one, which the tick would then
126
+ // archive near-empty.
127
+ const active = statSync(logger.path);
128
+ if (active.size >= maxBytes) {
129
+ lastRotatedLogPath = await moveLogFile(logger.path, rotatedLogDir, logger, compressArchives, active);
130
+ // The interval clock counts from the last rotation of any kind. Without this an
131
+ // instance whose uptime has passed `interval` archives a freshly-created log every
132
+ // interval on top of the size rotations already doing the work.
133
+ lastRotationTime = Date.now();
134
+ }
84
135
  } catch (err) {
85
- // If the log file doesn't exist, skip rotation
136
+ // A missing or already-rotated active log only invalidates this check; retention below
137
+ // must still run, so skip the check rather than leaving the whole tick.
138
+ recoverRotationTarget(err);
86
139
  if (err.code !== 'ENOENT') throw err;
87
140
  }
88
141
  }
89
- }
90
142
 
91
- if (maxInterval) {
92
- const minSinceLastRotate = Date.now() - lastRotationTime;
93
- if (minSinceLastRotate >= maxInterval) {
143
+ if (maxInterval) {
94
144
  try {
95
- lastRotatedLogPath = await moveLogFile(logger.path, rotatedLogDir, logger);
96
- lastRotationTime = Date.now();
145
+ const activeGeneration = generationIdentity(statSync(logger.path));
146
+ if (activeGeneration && activeGeneration !== observedGeneration) {
147
+ observedGeneration = activeGeneration;
148
+ lastRotationTime = Date.now();
149
+ }
97
150
  } catch (err) {
98
- // If the log file doesn't exist, skip rotation
99
151
  if (err.code !== 'ENOENT') throw err;
100
152
  }
153
+ if (Date.now() - lastRotationTime >= maxInterval) {
154
+ try {
155
+ lastRotatedLogPath = await moveLogFile(logger.path, rotatedLogDir, logger, compressArchives);
156
+ lastRotationTime = Date.now();
157
+ } catch (err) {
158
+ // If the log file doesn't exist, skip rotation
159
+ recoverRotationTarget(err);
160
+ if (err.code !== 'ENOENT') throw err;
161
+ }
162
+ }
101
163
  }
102
- }
103
- if (retention || reclamationPriority) {
104
- // remove old logs after retention time
105
- // adjust retention time if there is a reclamation priority in place
106
- const retentionMs = convertToMS(retention ?? '1M') / (1 + reclamationPriority);
107
- reclamationPriority = 0; // reset it after use
108
- let files;
109
- try {
110
- files = await fsProm.readdir(rotatedLogDir);
111
- } catch (err) {
112
- // The rotated log dir may not exist yet (nothing rotated so far); nothing to clean up
113
- if (err.code !== 'ENOENT') hdbLogger.error('Error reading rotated log directory', rotatedLogDir, err);
114
- files = [];
115
- }
116
- for (const file of files) {
164
+ // The compression sweep and retention both destroy archives this thread did not rotate, so
165
+ // both need the same proof: every peer releases any descriptor that is not on the live
166
+ // generation, and reports the log paths it is writing. One round trip per tick serves both,
167
+ // and it is not gated on retention being configured — retention is unset by default, and a
168
+ // worker's uncompressed archive still needs finishing.
169
+ if (compressArchives || retention || reclamationPriority) {
170
+ // Enumerated BEFORE the proof, and only these are destroyed: an archive created after the
171
+ // proof was never covered by it, and a peer blocked mid-rotation may still be writing to it.
172
+ let candidates;
117
173
  try {
118
- const fileStats = await fsProm.stat(path.join(rotatedLogDir, file));
119
- if (Date.now() - fileStats.mtimeMs > retentionMs) {
120
- await fsProm.unlink(path.join(rotatedLogDir, file));
121
- }
174
+ candidates = await fsProm.readdir(rotatedLogDir);
122
175
  } catch (err) {
123
- hdbLogger.error('Error trying to remove log', file, err);
176
+ if (err.code !== 'ENOENT') hdbLogger.error('Error reading rotated log directory', rotatedLogDir, err);
177
+ candidates = [];
178
+ }
179
+ const { released, liveLogPaths } = await requestStaleDescriptorRelease(tickDeadline);
180
+ // A peer whose event loop is blocked never answers, and the whole pass then destroys
181
+ // nothing — correct, but it is also the only thing bounding the rotated directory, so an
182
+ // operator who configured retention has to be able to see that it has stopped. Repeat at
183
+ // a low rate so a permanent stall does not disappear after one warning.
184
+ if (!released && Date.now() >= nextReleaseProofReport) {
185
+ nextReleaseProofReport = Date.now() + RELEASE_PROOF_REPORT_INTERVAL;
186
+ releaseProofStalled = true;
187
+ hdbLogger.warn(
188
+ `Log rotation could not prove every thread released its archived log descriptors; compression and retention are paused for ${rotatedLogDir}`
189
+ );
190
+ } else if (released && releaseProofStalled) {
191
+ releaseProofStalled = false;
192
+ nextReleaseProofReport = 0;
193
+ hdbLogger.notify(`Log rotation descriptor release recovered; retention resumed for ${rotatedLogDir}`);
194
+ }
195
+ const liveLogs = new Set([...liveLogPaths, logger.path].map((p) => path.resolve(p)));
196
+
197
+ if (released && (retention || reclamationPriority)) {
198
+ // remove old logs after retention time
199
+ // adjust retention time if there is a reclamation priority in place
200
+ const retentionMs = convertToMS(retention ?? '1M') / (1 + reclamationPriority);
201
+ let retentionCompleted = true;
202
+ let examined = 0;
203
+ for (; examined < candidates.length; examined++) {
204
+ if (ended || Date.now() >= tickDeadline) {
205
+ retentionCompleted = false;
206
+ break;
207
+ }
208
+ const file = candidates[(retentionCursor + examined) % candidates.length];
209
+ try {
210
+ const archivePath = path.join(rotatedLogDir, file);
211
+ // An explicitly configured rotation path may contain live component logs too.
212
+ if (liveLogs.has(path.resolve(archivePath))) continue;
213
+ // Unlinking an inode a stalled writer still holds loses whatever it writes next
214
+ // just as surely as compressing over it would.
215
+ if (isArchivePendingQuiescence(archivePath)) continue;
216
+ const fileStats = await fsProm.stat(archivePath);
217
+ if (Date.now() - fileStats.mtimeMs > retentionMs) {
218
+ await fsProm.unlink(archivePath);
219
+ }
220
+ } catch (err) {
221
+ if (err.code !== 'ENOENT') hdbLogger.error('Error trying to remove log', file, err);
222
+ }
223
+ }
224
+ if (retentionCompleted) {
225
+ retentionCursor = 0;
226
+ reclamationPriority = 0;
227
+ } else if (candidates.length) {
228
+ retentionCursor = (retentionCursor + examined) % candidates.length;
229
+ }
230
+ }
231
+
232
+ if (released && compressArchives && !ended) {
233
+ const compressionFailure = await compressPendingArchives(rotatedLogDir, candidates, liveLogs, {
234
+ deadline: Math.min(tickDeadline, Date.now() + compressionBudgetMs),
235
+ shouldStop: () => ended,
236
+ });
237
+ if (compressionFailure)
238
+ hdbLogger.error('Error compressing rotated log', compressionFailure.file, compressionFailure.error);
124
239
  }
125
240
  }
241
+ } catch (err) {
242
+ hdbLogger.error('Error during log rotation audit tick for', logger.path, err);
243
+ } finally {
244
+ try {
245
+ await retryPendingGenerations({ deadline: tickDeadline, shouldStop: () => ended });
246
+ } catch (err) {
247
+ hdbLogger.error('Error retrying pending log generations for', logger.path, err);
248
+ }
249
+ tickInFlight = false;
126
250
  }
127
- }, auditInterval ?? LOG_AUDIT_INTERVAL).unref();
251
+ }, auditIntervalMs).unref();
128
252
  return {
129
253
  end() {
254
+ ended = true;
130
255
  clearInterval(setIntervalId);
131
256
  },
132
257
  getLastRotatedLogPath() {
133
258
  return lastRotatedLogPath;
134
259
  },
135
260
  };
261
+
262
+ function generationIdentity(stats: any) {
263
+ return stats.ino ? `${stats.dev}:${stats.ino}` : undefined;
264
+ }
136
265
  }
137
266
 
138
- async function moveLogFile(logPath: string, rotatedLogPath: string, logger?: any) {
139
- const compress = envMgr.get(CONFIG_PARAMS.LOGGING_ROTATION_COMPRESS);
140
- let fullRotateLogPath = path.join(
267
+ async function moveLogFile(
268
+ logPath: string,
269
+ rotatedLogPath: string,
270
+ logger?: any,
271
+ compress?: boolean,
272
+ activeStats?: any
273
+ ) {
274
+ // The rename and the descriptor close must not be separated by an await: the descriptor would
275
+ // otherwise keep feeding the archived inode while the event loop runs. Closing the rotating
276
+ // logger's own descriptor (not the module-global one) is what makes the next write reopen a
277
+ // fresh log file rather than append to the moved — and, when compressing, unlinked — inode.
278
+ // `activeStats` is the caller's own stat of the live generation, when it has one: the size check
279
+ // must rename the generation it measured, and a second stat here could pick up a newer one.
280
+ const generation = rotateLogFileSync(
281
+ logPath,
141
282
  rotatedLogPath,
142
- `HDB-${new Date(Date.now()).toISOString().replaceAll(':', '-')}.log`
283
+ logger?.closeLogFile ?? hdbLogger.closeLogFile,
284
+ activeStats
285
+ );
286
+ const publishedPath = await publishArchivedGeneration(
287
+ generation,
288
+ compress ?? envMgr.get(CONFIG_PARAMS.LOGGING_ROTATION_COMPRESS),
289
+ (error) => hdbLogger.error('Error compressing rotated log', generation.archivePath, error)
143
290
  );
144
- // Move log file to rotated log path first (if we crash
145
- // during compression, we don't want to restart the compression with a new file)
146
- await fsProm.rename(logPath, fullRotateLogPath);
147
- // Close the rotating logger's own file descriptor now that the file has moved. This must be the
148
- // logger's own closeLogFile (which resets its internal logFD), not the module-global one — otherwise
149
- // the descriptor stays open on the moved (and, when compressing, subsequently unlinked) inode until the
150
- // logger's safety timeout fires, pinning disk space and sending any writes in that window into the
151
- // rotated/deleted file. Closing it here makes the next write reopen a fresh log file immediately.
152
- (logger?.closeLogFile ?? hdbLogger.closeLogFile)();
153
- if (compress) {
154
- logPath = fullRotateLogPath;
155
- fullRotateLogPath += '.gz';
156
- await pipe(createReadStream(logPath), createGzip(), createWriteStream(fullRotateLogPath));
157
- await fsProm.unlink(logPath);
158
- }
159
291
 
160
292
  // This notify log will create a new log file after the previous one has been rotated. It's important to keep this log as notify
161
- hdbLogger.notify(`hdb.log rotated, old log moved to ${fullRotateLogPath}`);
162
- return fullRotateLogPath;
293
+ hdbLogger.notify(`hdb.log rotated, old log moved to ${publishedPath}`);
294
+ return publishedPath;
163
295
  }
@@ -0,0 +1,45 @@
1
+ import { isIP } from 'node:net';
2
+
3
+ /**
4
+ * A node's identity — node.hostname, and the replication.hostname / certificate it falls back to —
5
+ * must be a bare hostname or IP literal, not a URL: it becomes the certificate common name and the
6
+ * host replication advertises and dials, so a scheme/port/path/non-string corrupts both (harper#2218,
7
+ * where "ws://http://host:9926:9925" resolves to host "http"). Returns a reason clause when `value`
8
+ * is not a bare host, else undefined. An empty string is "unset" (a caller's cue to fall back), not a
9
+ * violation.
10
+ */
11
+ export function bareHostViolation(value: unknown): string | undefined {
12
+ if (typeof value !== 'string') return `must be a string, but is a ${value === null ? 'null' : typeof value}`;
13
+ if (value === '') return undefined;
14
+ // The identity is stored unbracketed (bracketing belongs to URL construction). Reject a bracketed
15
+ // form so it is never cached — otherwise net.isIP fails on it and the certificate SAN is mistyped
16
+ // as DNS rather than IP, and the same node's identity string would differ by source.
17
+ if (value.includes('[') || value.includes(']'))
18
+ return 'must be an unbracketed IPv6 literal (e.g. "::1", not "[::1]")';
19
+ // A zone id ("fe80::1%eth0") passes net.isIP but has no valid URL authority, so exclude it here.
20
+ if (isIP(value) && !value.includes('%')) return undefined; // a bare IPv4/IPv6 literal is a valid identity
21
+ if (value.includes('://')) return 'must not include a URL scheme';
22
+ let url;
23
+ try {
24
+ // Parse under a special scheme so the host grammar matches the ws:// replication URLs that
25
+ // consume this value — a host this accepts is one the consumer accepts (a non-special scheme is
26
+ // more lenient and would pass e.g. "node%20" or "0x7f.1"). A port or path makes url.hostname
27
+ // differ from the input and is caught by the round-trip check below.
28
+ url = new URL(`https://${value}`);
29
+ } catch {
30
+ return 'is not a valid hostname';
31
+ }
32
+ // Report the port before the round-trip check: the parser strips a default port for the scheme it
33
+ // was given (":443" under https), which would otherwise surface as a vaguer "is not a bare hostname".
34
+ if (url.port || (url.hostname && value.slice(url.hostname.length).startsWith(':'))) {
35
+ return 'must not include a port';
36
+ }
37
+ if (url.username || url.password) return 'must not include credentials';
38
+ if (url.search) return 'must not include a query string';
39
+ if (url.hash) return 'must not include a fragment';
40
+ if (url.pathname && url.pathname !== '/') return 'must not include a path';
41
+ // The host must survive parsing unchanged (compared case-insensitively, since URL lowercases it);
42
+ // anything that does not round-trip carried extra syntax and is not a bare host.
43
+ if (url.hostname.toLowerCase() !== value.toLowerCase()) return 'is not a bare hostname';
44
+ return undefined;
45
+ }
@@ -12,7 +12,7 @@ import harperLogger from './logging/harper_logger.ts';
12
12
 
13
13
  import { CONFIG_PARAMS } from './hdbTerms.ts';
14
14
  import { getConfigPath } from '../config/configUtils.ts';
15
- import { nonInteractiveSpawn } from '../components/Application.ts';
15
+ import { nonInteractiveSpawn, packageManagerInstallArguments } from '../components/Application.ts';
16
16
  import { withComponentPreparationLock } from '../components/componentPreparationLock.ts';
17
17
  import { isThreadRunning } from '../server/threads/manageThreads.js';
18
18
 
@@ -26,18 +26,18 @@ export async function installModules(req: any) {
26
26
  'install_node_modules is deprecated. Dependencies are automatically installed on' +
27
27
  ' deploy, and install_node_modules can lead to inconsistent behavior';
28
28
  harperLogger.warn(deprecationWarning, req.projects);
29
- const validation = modulesValidator(req);
29
+ const { error: validation, value: validatedRequest } = modulesValidator(req);
30
30
  if (validation) {
31
31
  throw handleHDBError(validation, validation.message, HTTP_STATUS_CODES.BAD_REQUEST);
32
32
  }
33
33
 
34
- let { projects, dryRun } = req;
34
+ const { projects, dry_run: dryRun, allowInstallScripts } = validatedRequest;
35
35
 
36
36
  const componentsRootDirPath = getConfigPath(CONFIG_PARAMS.COMPONENTSROOT);
37
37
 
38
38
  const responseObject: any = {};
39
39
 
40
- const args = ['install', '--force', '--omit=dev', '--json'];
40
+ const args = [...packageManagerInstallArguments('npm', allowInstallScripts, true), '--json'];
41
41
  if (dryRun) args.push('--dry-run');
42
42
 
43
43
  for (const project of projects) {
@@ -91,15 +91,19 @@ function parseNPMStdErr(stderr: string) {
91
91
  }
92
92
 
93
93
  /**
94
- * Validator for both installModules & auditModules
94
+ * Validator for installModules
95
95
  * @param {Object} req
96
- * @returns {*}
97
96
  */
98
97
  function modulesValidator(req: any) {
98
+ // `dryRun` was the only spelling that worked before dry_run was honored; keep it accepted, but
99
+ // reject a request that carries both rather than picking a winner
99
100
  const funcSchema = Joi.object({
100
101
  projects: Joi.array().min(1).items(Joi.string()).required(),
101
102
  dry_run: Joi.boolean().default(false),
102
- });
103
+ allowInstallScripts: Joi.boolean().default(true),
104
+ })
105
+ .rename('dryRun', 'dry_run', { ignoreUndefined: true })
106
+ .rename('install_allow_scripts', 'allowInstallScripts', { ignoreUndefined: true });
103
107
 
104
- return validator.validateBySchema(req, funcSchema);
108
+ return validator.validateAndConvertBySchema(req, funcSchema);
105
109
  }
@@ -69,6 +69,7 @@ export const OPERATION_PERMISSION_GROUPS = {
69
69
  OPERATIONS_ENUM.INSERT,
70
70
  OPERATIONS_ENUM.UPDATE,
71
71
  OPERATIONS_ENUM.UPSERT,
72
+ OPERATIONS_ENUM.PUT,
72
73
  OPERATIONS_ENUM.DELETE,
73
74
  // Bulk load
74
75
  OPERATIONS_ENUM.CSV_DATA_LOAD,
@@ -97,6 +98,11 @@ const validGroups: Set<string> = new Set(Object.keys(OPERATION_PERMISSION_GROUPS
97
98
  // permission) whose names may fall outside OPERATIONS_ENUM. Tracked so they're grantable in a
98
99
  // role's `operations` allowlist (add_role/alter_role/impersonation validate against this set too).
99
100
  const dynamicallyRegisteredOps: Set<string> = new Set();
101
+ // The same, for ops registered on a WORKER and mirrored here by the OPERATION_REGISTERED bridge.
102
+ // Deliberately a separate set: the two threads can register the same name independently (a hot
103
+ // deploy can add a `startOnMainThread` component while the worker offering that name is retiring),
104
+ // so worker-lifecycle cleanup must not be able to revoke a mark this thread made itself.
105
+ const workerRegisteredOps: Set<string> = new Set();
100
106
 
101
107
  /**
102
108
  * Mark a dynamically-registered operation name as a valid target for role `operations` grants.
@@ -115,13 +121,24 @@ export function unregisterGrantableOperation(name: string): void {
115
121
  dynamicallyRegisteredOps.delete(name);
116
122
  }
117
123
 
124
+ export function registerWorkerGrantableOperation(name: string): void {
125
+ workerRegisteredOps.add(name);
126
+ }
127
+
128
+ export function unregisterWorkerGrantableOperation(name: string): void {
129
+ workerRegisteredOps.delete(name);
130
+ }
131
+
118
132
  /**
119
133
  * Validates that every entry in an operations array is a known operation name or group name.
120
134
  * Returns the first invalid entry, or null if all entries are valid.
121
135
  */
122
136
  export function validateOperations(operations: readonly unknown[]): string | null {
123
137
  for (const op of operations) {
124
- if (typeof op !== 'string' || (!validOps.has(op) && !validGroups.has(op) && !dynamicallyRegisteredOps.has(op))) {
138
+ if (
139
+ typeof op !== 'string' ||
140
+ (!validOps.has(op) && !validGroups.has(op) && !dynamicallyRegisteredOps.has(op) && !workerRegisteredOps.has(op))
141
+ ) {
125
142
  return String(op);
126
143
  }
127
144
  }