@harperfast/harper 5.2.9 → 5.3.0-alpha.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 (668) hide show
  1. package/agent/mcpTools.ts +1 -1
  2. package/agent/session.ts +25 -14
  3. package/bin/cliOperations.ts +46 -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 +59 -3
  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 +2414 -242
  14. package/components/ApplicationScope.ts +8 -0
  15. package/components/EntryHandler.ts +59 -39
  16. package/components/OptionsWatcher.ts +150 -74
  17. package/components/RuntimeModuleTracker.ts +38 -7
  18. package/components/Scope.ts +37 -15
  19. package/components/awaitRestart.ts +84 -0
  20. package/components/componentLoader.ts +340 -30
  21. package/components/componentPreparationLock.ts +16 -5
  22. package/components/mcp/adapters/harperHttp.ts +4 -0
  23. package/components/mcp/listChanged.ts +4 -0
  24. package/components/mcp/toolRegistry.ts +2 -0
  25. package/components/mcp/tools/operations.ts +9 -0
  26. package/components/mcp/tools/schemas/operationDescriptions.ts +2 -2
  27. package/components/operations.js +270 -78
  28. package/components/operationsValidation.js +49 -1
  29. package/components/status/ComponentStatusRegistry.ts +59 -0
  30. package/config/RootConfigWatcher.ts +80 -34
  31. package/config/configUtils.ts +291 -34
  32. package/config/harperConfigEnvVars.ts +170 -27
  33. package/config-root.schema.json +29 -0
  34. package/dataLayer/blobBackup.ts +160 -50
  35. package/dataLayer/delete.ts +6 -1
  36. package/dataLayer/harperBridge/ResourceBridge.ts +52 -8
  37. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
  38. package/dataLayer/hdbInfoController.ts +34 -1
  39. package/dataLayer/insert.ts +44 -1
  40. package/dataLayer/rocksdbBackup.ts +53 -10
  41. package/dataLayer/schema.ts +11 -1
  42. package/dataLayer/schemaDescribe.ts +8 -1
  43. package/dist/agent/mcpTools.js +1 -1
  44. package/dist/agent/mcpTools.js.map +1 -1
  45. package/dist/agent/session.d.ts +22 -0
  46. package/dist/agent/session.js +26 -15
  47. package/dist/agent/session.js.map +1 -1
  48. package/dist/bin/cliOperations.js +48 -9
  49. package/dist/bin/cliOperations.js.map +1 -1
  50. package/dist/bin/copyDb.d.ts +12 -1
  51. package/dist/bin/copyDb.js +248 -60
  52. package/dist/bin/copyDb.js.map +1 -1
  53. package/dist/bin/deploySetup.d.ts +2 -0
  54. package/dist/bin/deploySetup.js +11 -3
  55. package/dist/bin/deploySetup.js.map +1 -1
  56. package/dist/bin/harper.js +1 -1
  57. package/dist/bin/harper.js.map +1 -1
  58. package/dist/bin/help.js +4 -1
  59. package/dist/bin/help.js.map +1 -1
  60. package/dist/bin/lite.js +4 -1
  61. package/dist/bin/lite.js.map +1 -1
  62. package/dist/bin/restart.js +54 -5
  63. package/dist/bin/restart.js.map +1 -1
  64. package/dist/bin/run.js +4 -10
  65. package/dist/bin/run.js.map +1 -1
  66. package/dist/bin/upgrade.js +4 -3
  67. package/dist/bin/upgrade.js.map +1 -1
  68. package/dist/bin/workloadIdentity.d.ts +18 -0
  69. package/dist/bin/workloadIdentity.js +100 -0
  70. package/dist/bin/workloadIdentity.js.map +1 -0
  71. package/dist/components/Application.d.ts +139 -16
  72. package/dist/components/Application.js +2215 -267
  73. package/dist/components/Application.js.map +1 -1
  74. package/dist/components/ApplicationScope.d.ts +8 -0
  75. package/dist/components/ApplicationScope.js +7 -0
  76. package/dist/components/ApplicationScope.js.map +1 -1
  77. package/dist/components/EntryHandler.js +26 -10
  78. package/dist/components/EntryHandler.js.map +1 -1
  79. package/dist/components/OptionsWatcher.d.ts +1 -0
  80. package/dist/components/OptionsWatcher.js +141 -74
  81. package/dist/components/OptionsWatcher.js.map +1 -1
  82. package/dist/components/RuntimeModuleTracker.js +40 -6
  83. package/dist/components/RuntimeModuleTracker.js.map +1 -1
  84. package/dist/components/Scope.js +38 -13
  85. package/dist/components/Scope.js.map +1 -1
  86. package/dist/components/awaitRestart.d.ts +33 -0
  87. package/dist/components/awaitRestart.js +61 -0
  88. package/dist/components/awaitRestart.js.map +1 -0
  89. package/dist/components/componentLoader.d.ts +38 -1
  90. package/dist/components/componentLoader.js +279 -22
  91. package/dist/components/componentLoader.js.map +1 -1
  92. package/dist/components/componentPreparationLock.d.ts +5 -0
  93. package/dist/components/componentPreparationLock.js +14 -6
  94. package/dist/components/componentPreparationLock.js.map +1 -1
  95. package/dist/components/mcp/adapters/harperHttp.js +4 -0
  96. package/dist/components/mcp/adapters/harperHttp.js.map +1 -1
  97. package/dist/components/mcp/listChanged.js +5 -0
  98. package/dist/components/mcp/listChanged.js.map +1 -1
  99. package/dist/components/mcp/toolRegistry.d.ts +1 -0
  100. package/dist/components/mcp/toolRegistry.js.map +1 -1
  101. package/dist/components/mcp/tools/operations.d.ts +5 -0
  102. package/dist/components/mcp/tools/operations.js +9 -0
  103. package/dist/components/mcp/tools/operations.js.map +1 -1
  104. package/dist/components/mcp/tools/schemas/operationDescriptions.js +2 -2
  105. package/dist/components/mcp/tools/schemas/operationDescriptions.js.map +1 -1
  106. package/dist/components/operations.js +231 -77
  107. package/dist/components/operations.js.map +1 -1
  108. package/dist/components/operationsValidation.js +49 -1
  109. package/dist/components/operationsValidation.js.map +1 -1
  110. package/dist/components/status/ComponentStatusRegistry.d.ts +0 -4
  111. package/dist/components/status/ComponentStatusRegistry.js +63 -0
  112. package/dist/components/status/ComponentStatusRegistry.js.map +1 -1
  113. package/dist/config/RootConfigWatcher.d.ts +7 -1
  114. package/dist/config/RootConfigWatcher.js +64 -27
  115. package/dist/config/RootConfigWatcher.js.map +1 -1
  116. package/dist/config/configUtils.d.ts +9 -1
  117. package/dist/config/configUtils.js +254 -33
  118. package/dist/config/configUtils.js.map +1 -1
  119. package/dist/config/harperConfigEnvVars.d.ts +16 -0
  120. package/dist/config/harperConfigEnvVars.js +162 -25
  121. package/dist/config/harperConfigEnvVars.js.map +1 -1
  122. package/dist/dataLayer/blobBackup.d.ts +49 -20
  123. package/dist/dataLayer/blobBackup.js +139 -50
  124. package/dist/dataLayer/blobBackup.js.map +1 -1
  125. package/dist/dataLayer/delete.js +1 -1
  126. package/dist/dataLayer/delete.js.map +1 -1
  127. package/dist/dataLayer/harperBridge/ResourceBridge.d.ts +14 -1
  128. package/dist/dataLayer/harperBridge/ResourceBridge.js +51 -10
  129. package/dist/dataLayer/harperBridge/ResourceBridge.js.map +1 -1
  130. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.d.ts +3 -1
  131. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
  132. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js.map +1 -1
  133. package/dist/dataLayer/hdbInfoController.d.ts +10 -0
  134. package/dist/dataLayer/hdbInfoController.js +30 -1
  135. package/dist/dataLayer/hdbInfoController.js.map +1 -1
  136. package/dist/dataLayer/insert.d.ts +9 -1
  137. package/dist/dataLayer/insert.js +30 -0
  138. package/dist/dataLayer/insert.js.map +1 -1
  139. package/dist/dataLayer/rocksdbBackup.d.ts +2 -2
  140. package/dist/dataLayer/rocksdbBackup.js +45 -8
  141. package/dist/dataLayer/rocksdbBackup.js.map +1 -1
  142. package/dist/dataLayer/schema.js +8 -0
  143. package/dist/dataLayer/schema.js.map +1 -1
  144. package/dist/dataLayer/schemaDescribe.js +8 -1
  145. package/dist/dataLayer/schemaDescribe.js.map +1 -1
  146. package/dist/index.d.ts +1 -1
  147. package/dist/index.js.map +1 -1
  148. package/dist/json/systemSchema.json +52 -0
  149. package/dist/resources/DatabaseTransaction.d.ts +55 -0
  150. package/dist/resources/DatabaseTransaction.js +459 -45
  151. package/dist/resources/DatabaseTransaction.js.map +1 -1
  152. package/dist/resources/LMDBTransaction.js +22 -4
  153. package/dist/resources/LMDBTransaction.js.map +1 -1
  154. package/dist/resources/PrimaryRocksDatabase.d.ts +1 -0
  155. package/dist/resources/PrimaryRocksDatabase.js +29 -0
  156. package/dist/resources/PrimaryRocksDatabase.js.map +1 -1
  157. package/dist/resources/RecordEncoder.d.ts +20 -0
  158. package/dist/resources/RecordEncoder.js +94 -9
  159. package/dist/resources/RecordEncoder.js.map +1 -1
  160. package/dist/resources/RequestTarget.d.ts +2 -0
  161. package/dist/resources/RequestTarget.js.map +1 -1
  162. package/dist/resources/Resource.js +20 -11
  163. package/dist/resources/Resource.js.map +1 -1
  164. package/dist/resources/ResourceInterface.d.ts +20 -1
  165. package/dist/resources/ResourceInterface.js.map +1 -1
  166. package/dist/resources/RocksIndexStore.d.ts +6 -1
  167. package/dist/resources/RocksIndexStore.js +24 -9
  168. package/dist/resources/RocksIndexStore.js.map +1 -1
  169. package/dist/resources/RocksTransactionLogStore.d.ts +14 -1
  170. package/dist/resources/RocksTransactionLogStore.js +57 -17
  171. package/dist/resources/RocksTransactionLogStore.js.map +1 -1
  172. package/dist/resources/Table.d.ts +112 -8
  173. package/dist/resources/Table.js +1073 -191
  174. package/dist/resources/Table.js.map +1 -1
  175. package/dist/resources/auditStore.d.ts +11 -2
  176. package/dist/resources/auditStore.js +325 -71
  177. package/dist/resources/auditStore.js.map +1 -1
  178. package/dist/resources/blob.d.ts +129 -9
  179. package/dist/resources/blob.js +992 -114
  180. package/dist/resources/blob.js.map +1 -1
  181. package/dist/resources/branchDatabase.d.ts +48 -0
  182. package/dist/resources/branchDatabase.js +892 -0
  183. package/dist/resources/branchDatabase.js.map +1 -0
  184. package/dist/resources/crdt.js +50 -12
  185. package/dist/resources/crdt.js.map +1 -1
  186. package/dist/resources/databases.d.ts +150 -0
  187. package/dist/resources/databases.js +1200 -239
  188. package/dist/resources/databases.js.map +1 -1
  189. package/dist/resources/defineTable.d.ts +10 -2
  190. package/dist/resources/defineTable.js +9 -1
  191. package/dist/resources/defineTable.js.map +1 -1
  192. package/dist/resources/graphql.d.ts +1 -1
  193. package/dist/resources/graphql.js +50 -15
  194. package/dist/resources/graphql.js.map +1 -1
  195. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +1 -0
  196. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +6 -2
  197. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
  198. package/dist/resources/longLivedTransactions.d.ts +71 -0
  199. package/dist/resources/longLivedTransactions.js +358 -0
  200. package/dist/resources/longLivedTransactions.js.map +1 -0
  201. package/dist/resources/models/backendRegistry.d.ts +26 -0
  202. package/dist/resources/models/backendRegistry.js +60 -2
  203. package/dist/resources/models/backendRegistry.js.map +1 -1
  204. package/dist/resources/models/bootstrap.d.ts +33 -1
  205. package/dist/resources/models/bootstrap.js +416 -31
  206. package/dist/resources/models/bootstrap.js.map +1 -1
  207. package/dist/resources/recordLock.d.ts +80 -0
  208. package/dist/resources/recordLock.js +184 -0
  209. package/dist/resources/recordLock.js.map +1 -0
  210. package/dist/resources/replayLogs.d.ts +14 -1
  211. package/dist/resources/replayLogs.js +152 -24
  212. package/dist/resources/replayLogs.js.map +1 -1
  213. package/dist/resources/replayLogsGuards.d.ts +94 -7
  214. package/dist/resources/replayLogsGuards.js +111 -7
  215. package/dist/resources/replayLogsGuards.js.map +1 -1
  216. package/dist/resources/search.js +158 -6
  217. package/dist/resources/search.js.map +1 -1
  218. package/dist/resources/transactionBroadcast.d.ts +1 -1
  219. package/dist/resources/transactionBroadcast.js +2 -2
  220. package/dist/resources/transactionBroadcast.js.map +1 -1
  221. package/dist/security/auth.js +61 -30
  222. package/dist/security/auth.js.map +1 -1
  223. package/dist/security/authn/oidc/claims.d.ts +22 -0
  224. package/dist/security/authn/oidc/claims.js +71 -0
  225. package/dist/security/authn/oidc/claims.js.map +1 -0
  226. package/dist/security/authn/oidc/identityToken.d.ts +27 -0
  227. package/dist/security/authn/oidc/identityToken.js +111 -0
  228. package/dist/security/authn/oidc/identityToken.js.map +1 -0
  229. package/dist/security/authn/oidc/jwks.d.ts +25 -0
  230. package/dist/security/authn/oidc/jwks.js +261 -0
  231. package/dist/security/authn/oidc/jwks.js.map +1 -0
  232. package/dist/security/authn/oidc/providers/generic.d.ts +13 -0
  233. package/dist/security/authn/oidc/providers/generic.js +34 -0
  234. package/dist/security/authn/oidc/providers/generic.js.map +1 -0
  235. package/dist/security/authn/oidc/providers/githubActions.d.ts +11 -0
  236. package/dist/security/authn/oidc/providers/githubActions.js +129 -0
  237. package/dist/security/authn/oidc/providers/githubActions.js.map +1 -0
  238. package/dist/security/authn/oidc/providers/index.d.ts +37 -0
  239. package/dist/security/authn/oidc/providers/index.js +24 -0
  240. package/dist/security/authn/oidc/providers/index.js.map +1 -0
  241. package/dist/security/authn/oidc/tokenExchange.d.ts +12 -0
  242. package/dist/security/authn/oidc/tokenExchange.js +306 -0
  243. package/dist/security/authn/oidc/tokenExchange.js.map +1 -0
  244. package/dist/security/authn/oidc/trustPolicyOperations.d.ts +49 -0
  245. package/dist/security/authn/oidc/trustPolicyOperations.js +358 -0
  246. package/dist/security/authn/oidc/trustPolicyOperations.js.map +1 -0
  247. package/dist/security/authn/oidc/types.d.ts +38 -0
  248. package/dist/security/authn/oidc/types.js +6 -0
  249. package/dist/security/authn/oidc/types.js.map +1 -0
  250. package/dist/security/certificateVerification/index.js +40 -11
  251. package/dist/security/certificateVerification/index.js.map +1 -1
  252. package/dist/security/certificateVerification/trustedIssuers.d.ts +24 -0
  253. package/dist/security/certificateVerification/trustedIssuers.js +79 -0
  254. package/dist/security/certificateVerification/trustedIssuers.js.map +1 -0
  255. package/dist/security/certificateVerification/types.d.ts +1 -0
  256. package/dist/security/credentialProvenance.d.ts +35 -0
  257. package/dist/security/credentialProvenance.js +51 -0
  258. package/dist/security/credentialProvenance.js.map +1 -0
  259. package/dist/security/credentialRejection.d.ts +4 -0
  260. package/dist/security/credentialRejection.js +24 -0
  261. package/dist/security/credentialRejection.js.map +1 -0
  262. package/dist/security/deferredAuthentication.d.ts +36 -0
  263. package/dist/security/deferredAuthentication.js +70 -0
  264. package/dist/security/deferredAuthentication.js.map +1 -0
  265. package/dist/security/impersonation.d.ts +21 -0
  266. package/dist/security/impersonation.js +108 -9
  267. package/dist/security/impersonation.js.map +1 -1
  268. package/dist/security/jsLoader.d.ts +6 -0
  269. package/dist/security/jsLoader.js +75 -15
  270. package/dist/security/jsLoader.js.map +1 -1
  271. package/dist/security/keys.js +301 -71
  272. package/dist/security/keys.js.map +1 -1
  273. package/dist/security/operationScope.d.ts +21 -0
  274. package/dist/security/operationScope.js +36 -0
  275. package/dist/security/operationScope.js.map +1 -0
  276. package/dist/security/permissionsTranslator.js +21 -0
  277. package/dist/security/permissionsTranslator.js.map +1 -1
  278. package/dist/security/tokenAuthentication.d.ts +19 -1
  279. package/dist/security/tokenAuthentication.js +191 -10
  280. package/dist/security/tokenAuthentication.js.map +1 -1
  281. package/dist/security/user.js +4 -3
  282. package/dist/security/user.js.map +1 -1
  283. package/dist/server/DurableSubscriptionsSession.d.ts +2 -2
  284. package/dist/server/DurableSubscriptionsSession.js +67 -10
  285. package/dist/server/DurableSubscriptionsSession.js.map +1 -1
  286. package/dist/server/REST.js +73 -0
  287. package/dist/server/REST.js.map +1 -1
  288. package/dist/server/graphqlQuerying.js +4 -0
  289. package/dist/server/graphqlQuerying.js.map +1 -1
  290. package/dist/server/http.d.ts +11 -0
  291. package/dist/server/http.js +88 -15
  292. package/dist/server/http.js.map +1 -1
  293. package/dist/server/itc/serverHandlers.js +8 -1
  294. package/dist/server/itc/serverHandlers.js.map +1 -1
  295. package/dist/server/jobs/jobProcess.js +6 -2
  296. package/dist/server/jobs/jobProcess.js.map +1 -1
  297. package/dist/server/jobs/jobs.js +4 -1
  298. package/dist/server/jobs/jobs.js.map +1 -1
  299. package/dist/server/liveSubscriptionAuth.d.ts +26 -4
  300. package/dist/server/liveSubscriptionAuth.js +105 -39
  301. package/dist/server/liveSubscriptionAuth.js.map +1 -1
  302. package/dist/server/loadRootComponents.js +49 -10
  303. package/dist/server/loadRootComponents.js.map +1 -1
  304. package/dist/server/mqtt.d.ts +2 -0
  305. package/dist/server/mqtt.js +165 -30
  306. package/dist/server/mqtt.js.map +1 -1
  307. package/dist/server/nodeName.d.ts +2 -0
  308. package/dist/server/nodeName.js +107 -23
  309. package/dist/server/nodeName.js.map +1 -1
  310. package/dist/server/serverHelpers/Headers.d.ts +25 -0
  311. package/dist/server/serverHelpers/Headers.js +139 -1
  312. package/dist/server/serverHelpers/Headers.js.map +1 -1
  313. package/dist/server/serverHelpers/contentTypes.d.ts +9 -0
  314. package/dist/server/serverHelpers/contentTypes.js +32 -25
  315. package/dist/server/serverHelpers/contentTypes.js.map +1 -1
  316. package/dist/server/serverHelpers/deployValidationState.d.ts +3 -0
  317. package/dist/server/serverHelpers/deployValidationState.js +9 -19
  318. package/dist/server/serverHelpers/deployValidationState.js.map +1 -1
  319. package/dist/server/serverHelpers/operationAuthorizationState.d.ts +12 -0
  320. package/dist/server/serverHelpers/operationAuthorizationState.js +24 -2
  321. package/dist/server/serverHelpers/operationAuthorizationState.js.map +1 -1
  322. package/dist/server/serverHelpers/registeredOperations.d.ts +5 -4
  323. package/dist/server/serverHelpers/registeredOperations.js +74 -21
  324. package/dist/server/serverHelpers/registeredOperations.js.map +1 -1
  325. package/dist/server/serverHelpers/requestSanitization.d.ts +11 -0
  326. package/dist/server/serverHelpers/requestSanitization.js +20 -0
  327. package/dist/server/serverHelpers/requestSanitization.js.map +1 -0
  328. package/dist/server/serverHelpers/serverHandlers.js +6 -3
  329. package/dist/server/serverHelpers/serverHandlers.js.map +1 -1
  330. package/dist/server/serverHelpers/serverUtilities.d.ts +18 -0
  331. package/dist/server/serverHelpers/serverUtilities.js +90 -20
  332. package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
  333. package/dist/server/serverHelpers/sharedMessageEncoding.d.ts +67 -0
  334. package/dist/server/serverHelpers/sharedMessageEncoding.js +280 -0
  335. package/dist/server/serverHelpers/sharedMessageEncoding.js.map +1 -0
  336. package/dist/server/serverHelpers/uwsServer.js +19 -1
  337. package/dist/server/serverHelpers/uwsServer.js.map +1 -1
  338. package/dist/server/static.js +24 -28
  339. package/dist/server/static.js.map +1 -1
  340. package/dist/server/storageReclamation.d.ts +12 -0
  341. package/dist/server/storageReclamation.js +26 -0
  342. package/dist/server/storageReclamation.js.map +1 -1
  343. package/dist/server/threads/itc.d.ts +7 -2
  344. package/dist/server/threads/itc.js +5 -1
  345. package/dist/server/threads/itc.js.map +1 -1
  346. package/dist/server/threads/manageThreads.d.ts +26 -3
  347. package/dist/server/threads/manageThreads.js +517 -65
  348. package/dist/server/threads/manageThreads.js.map +1 -1
  349. package/dist/server/threads/socketRouter.js +89 -26
  350. package/dist/server/threads/socketRouter.js.map +1 -1
  351. package/dist/server/threads/threadHeapMemory.d.ts +2 -0
  352. package/dist/server/threads/threadHeapMemory.js +31 -0
  353. package/dist/server/threads/threadHeapMemory.js.map +1 -0
  354. package/dist/server/threads/threadServer.js +46 -15
  355. package/dist/server/threads/threadServer.js.map +1 -1
  356. package/dist/sqlEngine/config.d.ts +1 -3
  357. package/dist/sqlEngine/config.js +19 -16
  358. package/dist/sqlEngine/config.js.map +1 -1
  359. package/dist/sqlTranslator/index.d.ts +1 -1
  360. package/dist/sqlTranslator/index.js +30 -7
  361. package/dist/sqlTranslator/index.js.map +1 -1
  362. package/dist/upgrade/directives/5-3-0.d.ts +7 -0
  363. package/dist/upgrade/directives/5-3-0.js +148 -0
  364. package/dist/upgrade/directives/5-3-0.js.map +1 -0
  365. package/dist/upgrade/directives/directivesController.js +2 -1
  366. package/dist/upgrade/directives/directivesController.js.map +1 -1
  367. package/dist/utility/OperationFunctionCaller.js +2 -1
  368. package/dist/utility/OperationFunctionCaller.js.map +1 -1
  369. package/dist/utility/common_utils.d.ts +16 -0
  370. package/dist/utility/common_utils.js +32 -6
  371. package/dist/utility/common_utils.js.map +1 -1
  372. package/dist/utility/componentNames.d.ts +8 -0
  373. package/dist/utility/componentNames.js +12 -1
  374. package/dist/utility/componentNames.js.map +1 -1
  375. package/dist/utility/environment/environmentManager.js +3 -6
  376. package/dist/utility/environment/environmentManager.js.map +1 -1
  377. package/dist/utility/environment/systemInformation.d.ts +1 -0
  378. package/dist/utility/environment/systemInformation.js +1 -0
  379. package/dist/utility/environment/systemInformation.js.map +1 -1
  380. package/dist/utility/errors/commonErrors.d.ts +2 -0
  381. package/dist/utility/errors/commonErrors.js +2 -0
  382. package/dist/utility/errors/commonErrors.js.map +1 -1
  383. package/dist/utility/errors/hdbError.d.ts +17 -0
  384. package/dist/utility/errors/hdbError.js +30 -1
  385. package/dist/utility/errors/hdbError.js.map +1 -1
  386. package/dist/utility/globalSchema.d.ts +18 -0
  387. package/dist/utility/hdbTerms.d.ts +16 -0
  388. package/dist/utility/hdbTerms.js +18 -2
  389. package/dist/utility/hdbTerms.js.map +1 -1
  390. package/dist/utility/logging/harper_logger.d.ts +2 -0
  391. package/dist/utility/logging/harper_logger.js +91 -14
  392. package/dist/utility/logging/harper_logger.js.map +1 -1
  393. package/dist/utility/logging/logRotator.js +76 -49
  394. package/dist/utility/logging/logRotator.js.map +1 -1
  395. package/dist/utility/nodeIdentity.d.ts +9 -0
  396. package/dist/utility/nodeIdentity.js +58 -0
  397. package/dist/utility/nodeIdentity.js.map +1 -0
  398. package/dist/utility/npmUtilities.js +9 -7
  399. package/dist/utility/npmUtilities.js.map +1 -1
  400. package/dist/utility/operationPermissions.d.ts +3 -1
  401. package/dist/utility/operationPermissions.js +16 -1
  402. package/dist/utility/operationPermissions.js.map +1 -1
  403. package/dist/utility/operation_authorization.d.ts +10 -7
  404. package/dist/utility/operation_authorization.js +212 -41
  405. package/dist/utility/operation_authorization.js.map +1 -1
  406. package/dist/utility/watchPath.d.ts +29 -0
  407. package/dist/utility/watchPath.js +68 -0
  408. package/dist/utility/watchPath.js.map +1 -0
  409. package/dist/utility/watcherFallback.d.ts +86 -0
  410. package/dist/utility/watcherFallback.js +278 -1
  411. package/dist/utility/watcherFallback.js.map +1 -1
  412. package/dist/validation/configValidator.d.ts +12 -0
  413. package/dist/validation/configValidator.js +199 -72
  414. package/dist/validation/configValidator.js.map +1 -1
  415. package/dist/validation/installValidator.js +12 -0
  416. package/dist/validation/installValidator.js.map +1 -1
  417. package/dist/validation/validationWrapper.d.ts +11 -0
  418. package/dist/validation/validationWrapper.js +16 -3
  419. package/dist/validation/validationWrapper.js.map +1 -1
  420. package/index.ts +2 -0
  421. package/json/systemSchema.json +52 -0
  422. package/npm-shrinkwrap.json +196 -194
  423. package/package.json +7 -6
  424. package/resources/DESIGN.md +114 -52
  425. package/resources/DatabaseTransaction.ts +521 -43
  426. package/resources/LMDBTransaction.ts +26 -4
  427. package/resources/PrimaryRocksDatabase.ts +28 -1
  428. package/resources/RecordEncoder.ts +103 -8
  429. package/resources/RequestTarget.ts +2 -0
  430. package/resources/Resource.ts +17 -9
  431. package/resources/ResourceInterface.ts +23 -0
  432. package/resources/RocksIndexStore.ts +30 -9
  433. package/resources/RocksTransactionLogStore.ts +78 -21
  434. package/resources/Table.ts +1110 -159
  435. package/resources/auditStore.ts +331 -73
  436. package/resources/blob.ts +1029 -110
  437. package/resources/branchDatabase.ts +941 -0
  438. package/resources/crdt.ts +76 -12
  439. package/resources/databases.ts +1310 -252
  440. package/resources/defineTable.ts +18 -2
  441. package/resources/graphql.ts +70 -16
  442. package/resources/indexes/HierarchicalNavigableSmallWorld.ts +6 -2
  443. package/resources/longLivedTransactions.ts +360 -0
  444. package/resources/models/backendRegistry.ts +84 -2
  445. package/resources/models/bootstrap.ts +473 -28
  446. package/resources/recordLock.ts +253 -0
  447. package/resources/replayLogs.ts +147 -26
  448. package/resources/replayLogsGuards.ts +171 -8
  449. package/resources/search.ts +154 -7
  450. package/resources/transactionBroadcast.ts +3 -3
  451. package/security/auth.ts +68 -29
  452. package/security/authn/oidc/claims.ts +72 -0
  453. package/security/authn/oidc/identityToken.ts +129 -0
  454. package/security/authn/oidc/jwks.ts +260 -0
  455. package/security/authn/oidc/providers/generic.ts +40 -0
  456. package/security/authn/oidc/providers/githubActions.ts +137 -0
  457. package/security/authn/oidc/providers/index.ts +52 -0
  458. package/security/authn/oidc/tokenExchange.ts +300 -0
  459. package/security/authn/oidc/trustPolicyOperations.ts +343 -0
  460. package/security/authn/oidc/types.ts +41 -0
  461. package/security/certificateVerification/index.ts +54 -13
  462. package/security/certificateVerification/trustedIssuers.ts +76 -0
  463. package/security/certificateVerification/types.ts +1 -0
  464. package/security/credentialProvenance.ts +47 -0
  465. package/security/credentialRejection.ts +22 -0
  466. package/security/deferredAuthentication.ts +71 -0
  467. package/security/impersonation.ts +117 -12
  468. package/security/jsLoader.ts +81 -18
  469. package/security/keys.ts +298 -72
  470. package/security/operationScope.ts +33 -0
  471. package/security/permissionsTranslator.js +23 -0
  472. package/security/tokenAuthentication.ts +233 -12
  473. package/security/user.ts +4 -3
  474. package/server/DESIGN.md +183 -16
  475. package/server/DurableSubscriptionsSession.ts +71 -11
  476. package/server/REST.ts +79 -1
  477. package/server/graphqlQuerying.ts +4 -0
  478. package/server/http.ts +99 -18
  479. package/server/itc/serverHandlers.js +8 -1
  480. package/server/jobs/jobProcess.ts +8 -2
  481. package/server/jobs/jobs.ts +4 -1
  482. package/server/liveSubscriptionAuth.ts +129 -46
  483. package/server/loadRootComponents.js +50 -8
  484. package/server/mqtt.ts +179 -38
  485. package/server/nodeName.ts +103 -21
  486. package/server/serverHelpers/Headers.ts +131 -0
  487. package/server/serverHelpers/contentTypes.ts +29 -21
  488. package/server/serverHelpers/deployValidationState.ts +24 -13
  489. package/server/serverHelpers/operationAuthorizationState.ts +34 -3
  490. package/server/serverHelpers/registeredOperations.ts +79 -22
  491. package/server/serverHelpers/requestSanitization.ts +15 -0
  492. package/server/serverHelpers/serverHandlers.js +6 -3
  493. package/server/serverHelpers/serverUtilities.ts +104 -31
  494. package/server/serverHelpers/sharedMessageEncoding.ts +307 -0
  495. package/server/serverHelpers/uwsServer.ts +17 -2
  496. package/server/static.ts +23 -29
  497. package/server/storageReclamation.ts +23 -0
  498. package/server/threads/itc.js +11 -1
  499. package/server/threads/manageThreads.js +526 -56
  500. package/server/threads/socketRouter.ts +81 -26
  501. package/server/threads/threadHeapMemory.ts +26 -0
  502. package/server/threads/threadServer.js +43 -15
  503. package/sqlTranslator/index.ts +31 -8
  504. package/studio/web/assets/Chat-BnCBegQz.js +2267 -0
  505. package/studio/web/assets/FloatingChat-CoDW1ySS.js +23 -0
  506. package/studio/web/assets/{abnfDiagram-VCTEODGH-C0_BAZyO.js → abnfDiagram-VCTEODGH-B0BebmD2.js} +1 -1
  507. package/studio/web/assets/{alertDialog-DIHt7Z0r.js → alertDialog-CQyAJJhl.js} +1 -1
  508. package/studio/web/assets/{apiToken-c3Rd-w6g.js → apiToken-Bwk5BLXW.js} +1 -1
  509. package/studio/web/assets/applications-DHxGi7JH.js +296 -0
  510. package/studio/web/assets/architecture-7GRP2DOG-LB-MLAAb.js +1 -0
  511. package/studio/web/assets/{architectureDiagram-5GKGNRK7-BWzrASgm.js → architectureDiagram-5GKGNRK7-7SW3GD-K.js} +1 -1
  512. package/studio/web/assets/authStore-C3Nfubqr.js +3 -0
  513. package/studio/web/assets/{blockDiagram-NRAW4CY4-BdJX9Khj.js → blockDiagram-I7D4REHJ-BqguiadH.js} +2 -2
  514. package/studio/web/assets/{button-DhiX-njv.js → button-BIsUKRZq.js} +2 -2
  515. package/studio/web/assets/{c4Diagram-UCG6FXSJ-CI6MzGmQ.js → c4Diagram-7LVT6UL2-LBNf8t_X.js} +1 -1
  516. package/studio/web/assets/channel-yictG-U-.js +1 -0
  517. package/studio/web/assets/{chevron-up-Df2c8uoU.js → chevron-up-DtKGqDn3.js} +1 -1
  518. package/studio/web/assets/{chunk-TEH6E4GO-P87k5mNi.js → chunk-4HAMMTFA-DWtTut21.js} +1 -1
  519. package/studio/web/assets/{chunk-75Z2AOVW-BT8tVmks.js → chunk-75Z2AOVW-QGQD6th2.js} +1 -1
  520. package/studio/web/assets/{chunk-DU6HZSFF-9kAOOmI6.js → chunk-DU6HZSFF-Chq20Ba5.js} +1 -1
  521. package/studio/web/assets/{chunk-F27PBJKO-BW7ao8AY.js → chunk-F27PBJKO-BVA5EPhV.js} +1 -1
  522. package/studio/web/assets/{chunk-GMAD6QVW-BNyXpoQO.js → chunk-GMAD6QVW-BeS7S07A.js} +1 -1
  523. package/studio/web/assets/{chunk-OBVCFTLP-D4wWOqDQ.js → chunk-GVQU2GXP-sbwVIQ8i.js} +1 -1
  524. package/studio/web/assets/{chunk-G27WJ6UU-COyLMcgK.js → chunk-IMKFNOWR-Bnh3tAVd.js} +1 -1
  525. package/studio/web/assets/{chunk-JQ64N6SF-Cyz1IeLf.js → chunk-L3NEJ4N5-COfUyKII.js} +1 -1
  526. package/studio/web/assets/chunk-OSK3NFVY-ByciRftO.js +10 -0
  527. package/studio/web/assets/{chunk-P2QGCYS3-DmIFY4d7.js → chunk-P2QGCYS3-CP1VhG_c.js} +1 -1
  528. package/studio/web/assets/{chunk-POPQ4Y6H-BPrvMyKz.js → chunk-POPQ4Y6H-ClWhhkwW.js} +1 -1
  529. package/studio/web/assets/{chunk-PWAF6VOD-2zB6IW9i.js → chunk-PWAF6VOD-1z1THyS5.js} +1 -1
  530. package/studio/web/assets/{chunk-RHFEMEQ7-2FgyI8YU.js → chunk-SHT3W25Y-LpQkMsah.js} +2 -2
  531. package/studio/web/assets/{chunk-SVP7TREG-FwtbH2QC.js → chunk-SVP7TREG-jtdAHw0S.js} +1 -1
  532. package/studio/web/assets/{chunk-LCL6LL3I-HOzK_ppE.js → chunk-TICWLB2K-VOwzetX-.js} +1 -1
  533. package/studio/web/assets/classDiagram-ZZMXUADV-VaEwSy_g.js +1 -0
  534. package/studio/web/assets/classDiagram-v2-VYDZK3BY-VaEwSy_g.js +1 -0
  535. package/studio/web/assets/{createLucideIcon-BKGPfjm2.js → createLucideIcon-CzW9508A.js} +1 -1
  536. package/studio/web/assets/{cssMode-CEN2mzSA.js → cssMode-s0cWI-_M.js} +1 -1
  537. package/studio/web/assets/{cynefin-OW5HDTMX-BRkpLFQV.js → cynefin-OW5HDTMX-BbdbCvub.js} +1 -1
  538. package/studio/web/assets/{cynefinDiagram-5FMLGOSQ-CHT1DaX6.js → cynefinDiagram-5FMLGOSQ-TP-aIqbt.js} +1 -1
  539. package/studio/web/assets/{dagre-3AP2YEHR-DpUXBh63.js → dagre-GXQ25YYZ-DShnGpGo.js} +1 -1
  540. package/studio/web/assets/{diagram-S7CK7UJ4-BuymVFZT.js → diagram-S7CK7UJ4-aoCVTtcy.js} +1 -1
  541. package/studio/web/assets/{diagram-UQ7AKVKN-CyP148RM.js → diagram-UQ7AKVKN-DglXtQ6x.js} +1 -1
  542. package/studio/web/assets/{diagram-VSXAHHWV-CoCAg3M9.js → diagram-VSXAHHWV-fhEdmkwM.js} +1 -1
  543. package/studio/web/assets/{diagram-VX7I27RA-BpOqCFca.js → diagram-VX7I27RA-DccVJet6.js} +1 -1
  544. package/studio/web/assets/{diagram-Z3DM3KII-Bfpw7Vbj.js → diagram-Z3DM3KII-D-RyJJb7.js} +1 -1
  545. package/studio/web/assets/{dialog-CBf0Mr1d.js → dialog-Cn2uWgD4.js} +1 -1
  546. package/studio/web/assets/{dist-lkA3O3eM.js → dist-DP8UjMB_.js} +1 -1
  547. package/studio/web/assets/{download-BtTOBem-.js → download-B5T5r7ss.js} +1 -1
  548. package/studio/web/assets/{ebnfDiagram-PWID7BFC-DS_6aWqL.js → ebnfDiagram-PWID7BFC-DJGpIpz_.js} +1 -1
  549. package/studio/web/assets/{editor-D8oDeCTL.js → editor-DNcRHK54.js} +1 -1
  550. package/studio/web/assets/{erDiagram-SSCWMZ5O-DJNk6Fgw.js → erDiagram-RLTQ6QDP-CIfNlgkC.js} +1 -1
  551. package/studio/web/assets/eventmodeling-NTZA5JFV-CLxnp2CR.js +1 -0
  552. package/studio/web/assets/flowDiagram-HODETNUW-BIbhmz9f.js +1 -0
  553. package/studio/web/assets/{ganttDiagram-EL5Y4UJY-2pOExxMY.js → ganttDiagram-EL5Y4UJY-BxToTzzD.js} +1 -1
  554. package/studio/web/assets/{getAnalytics-D4LKGeVy.js → getAnalytics-GHK8ORfM.js} +1 -1
  555. package/studio/web/assets/{gitGraph-4MIJSDKK-CH5ZxwzF.js → gitGraph-4MIJSDKK-D2s2w8lE.js} +1 -1
  556. package/studio/web/assets/{gitGraphDiagram-WWUBYQGX-DVIsIhbO.js → gitGraphDiagram-WWUBYQGX-Dwntd4-x.js} +1 -1
  557. package/studio/web/assets/{html-u3vOg7LJ.js → html-Bdssedlg.js} +1 -1
  558. package/studio/web/assets/{htmlMode-DyO31v-P.js → htmlMode-CoDlJ3fw.js} +1 -1
  559. package/studio/web/assets/{index-Cxj2_wsl.css → index-7RMEgVG1.css} +1 -1
  560. package/studio/web/assets/index-D6sxmFLR.js +824 -0
  561. package/studio/web/assets/index.lazy-tmU5BS8s.js +2 -0
  562. package/studio/web/assets/{info-A6RAGUB7-CPQfTnaG.js → info-A6RAGUB7-DYjkvb0C.js} +1 -1
  563. package/studio/web/assets/{infoDiagram-RXCK75RN-DlwLYlwm.js → infoDiagram-27XIBGKW-Bnp1FJE5.js} +1 -1
  564. package/studio/web/assets/{ishikawaDiagram-5VMMS53U-BRXRp29U.js → ishikawaDiagram-5VMMS53U-D9Xh2r6X.js} +1 -1
  565. package/studio/web/assets/{javascript-CUvxOyTC.js → javascript-B8meVSTH.js} +1 -1
  566. package/studio/web/assets/{journeyDiagram-EYS64GPL-B0ou8k0n.js → journeyDiagram-3NMN7TZE-CokIi6ll.js} +2 -2
  567. package/studio/web/assets/{jsonMode-f_IwbF3D.js → jsonMode-DpIPd35T.js} +1 -1
  568. package/studio/web/assets/{kanban-definition-3QL26DDD-uYg7iYzp.js → kanban-definition-UXKFOSKX-CukSFJfX.js} +1 -1
  569. package/studio/web/assets/{languageServices-DXtZ6rEF.js → languageServices-C_5FMJzQ.js} +1 -1
  570. package/studio/web/assets/{lspLanguageFeatures-B4pCF1zO.js → lspLanguageFeatures-BIzNBzPK.js} +1 -1
  571. package/studio/web/assets/{mermaid-parser.core-Ck-fC8b7.js → mermaid-parser.core-BlEsOWNO.js} +3 -3
  572. package/studio/web/assets/{mermaid.core-CP8aNNYm.js → mermaid.core-BlkGaMIH.js} +5 -5
  573. package/studio/web/assets/{mindmap-definition-FBJOCRG2-CgTZ-rit.js → mindmap-definition-YA3MSWOX-IprMc_0j.js} +1 -1
  574. package/studio/web/assets/{notifications-D3tIQ4sg.js → notifications-CQf18QKb.js} +1 -1
  575. package/studio/web/assets/notifications-CvZivSbh.js +1 -0
  576. package/studio/web/assets/{packet-AYTQ26CC-DEyoPtPb.js → packet-AYTQ26CC-Bi3V04Zi.js} +1 -1
  577. package/studio/web/assets/{pegDiagram-XKGWAZYB-DrD-7sD9.js → pegDiagram-XKGWAZYB-BNuPDLZY.js} +1 -1
  578. package/studio/web/assets/{pie-WAS4IAKB-wjj-EI1d.js → pie-WAS4IAKB-_6DoDbng.js} +1 -1
  579. package/studio/web/assets/{pieDiagram-E7YTZNPT-GntqDCzv.js → pieDiagram-E7YTZNPT-DqNb6Ht2.js} +1 -1
  580. package/studio/web/assets/{profile-DZWU7MgT.js → profile-DdOwtntb.js} +1 -1
  581. package/studio/web/assets/{quadrantDiagram-AXDQQJYC-0UeqXQGd.js → quadrantDiagram-AXDQQJYC-BGH9E2YR.js} +1 -1
  582. package/studio/web/assets/{radar-RG4KPBEZ-DFSA5h7k.js → radar-RG4KPBEZ-DDdVczcL.js} +1 -1
  583. package/studio/web/assets/{railroad-74A4TZTK-CaOUG9wR.js → railroad-74A4TZTK-BJUP4Jds.js} +1 -1
  584. package/studio/web/assets/railroad-abnf-HS5TGJTU-Bm3L1L0h.js +1 -0
  585. package/studio/web/assets/railroad-ebnf-LZEXJU2U-CKzLGlkw.js +1 -0
  586. package/studio/web/assets/railroad-peg-WCYAUIDC-S8xLjslx.js +1 -0
  587. package/studio/web/assets/{railroadDiagram-O6MQD6OU-yHUELZaV.js → railroadDiagram-O6MQD6OU-DGTPh2KZ.js} +1 -1
  588. package/studio/web/assets/{regions-CkyurXzE.js → regions-n69fwagr.js} +1 -1
  589. package/studio/web/assets/{register-BUyhWjBO.js → register-PfWTCXWB.js} +3 -3
  590. package/studio/web/assets/{requirementDiagram-EFPCY7ZU-DNEGFjuW.js → requirementDiagram-BXWQKSXE-BJnO6uLz.js} +1 -1
  591. package/studio/web/assets/{sankeyDiagram-P5KCCOFB-DpyAmSVR.js → sankeyDiagram-P5KCCOFB-0vSOdymH.js} +1 -1
  592. package/studio/web/assets/{sequenceDiagram-WJ2MYXX4-TyaT7xNk.js → sequenceDiagram-WJ2MYXX4-hETizDWE.js} +1 -1
  593. package/studio/web/assets/{setComponentFile-CeyKSZAa.js → setComponentFile-Bg6O7X0S.js} +1 -1
  594. package/studio/web/assets/{setup-D2kn7cAA.js → setup-CUx_aUDl.js} +2 -2
  595. package/studio/web/assets/{stateDiagram-HBIQ2CUA-CeEdTArZ.js → stateDiagram-D77RDMKH-CdYQ_KtC.js} +1 -1
  596. package/studio/web/assets/stateDiagram-v2-MP3YSRHH-CdKuzQMT.js +1 -0
  597. package/studio/web/assets/status-D7BVKqX9.js +61 -0
  598. package/studio/web/assets/{swimlanes-XN3QIQJK-B54FmF46.js → swimlanes-42K2YHIH-B8cHIpU4.js} +1 -1
  599. package/studio/web/assets/swimlanesDiagram-VR7AAH4N-DmOSJwaH.js +8 -0
  600. package/studio/web/assets/{tabs-B_G5zscN.js → tabs-BrHu7gJi.js} +1 -1
  601. package/studio/web/assets/{timeline-definition-24CTP7MA-D-a9ujbo.js → timeline-definition-24CTP7MA-BJWYSXqF.js} +1 -1
  602. package/studio/web/assets/{toggleHighContrast-C0UW6rI2.js → toggleHighContrast-DBSyXzMr.js} +1 -1
  603. package/studio/web/assets/{treeView-Q6P3EWNA-CrW_6JnS.js → treeView-Q6P3EWNA-qxe_v6CQ.js} +1 -1
  604. package/studio/web/assets/{treemap-WGGIJYW6-BxyYLdP_.js → treemap-WGGIJYW6-dDo97XXF.js} +1 -1
  605. package/studio/web/assets/{tsMode-DBC0zmDx.js → tsMode-BByKCjBS.js} +1 -1
  606. package/studio/web/assets/{typescript-DApRQir3.js → typescript-DDLnLpw9.js} +1 -1
  607. package/studio/web/assets/{useEntityRestURL-DB6JStU1.js → useEntityRestURL-31CHGaHk.js} +1 -1
  608. package/studio/web/assets/{useLocalStorage-Dtj1QS8_.js → useLocalStorage-BqMR3D8_.js} +1 -1
  609. package/studio/web/assets/vendor-core-c2JRRJpV.js +58 -0
  610. package/studio/web/assets/vendor-datadog-CLUcJXOo.js +6 -0
  611. package/studio/web/assets/{vendor-react-Dyj4O3HE.js → vendor-react-CJV_K1u4.js} +1 -1
  612. package/studio/web/assets/vendor-tanstack-DxzraizX.js +1 -0
  613. package/studio/web/assets/{vendor-ui-vhu-UHhF.js → vendor-ui-BUjK0h8a.js} +2 -2
  614. package/studio/web/assets/{vennDiagram-4TSXK5OY-Cy7s7Mpy.js → vennDiagram-4TSXK5OY-A3i-lCdl.js} +1 -1
  615. package/studio/web/assets/{wardley-WFR3VGLG-BeBL35g2.js → wardley-WFR3VGLG-B0ik-_6g.js} +1 -1
  616. package/studio/web/assets/{wardleyDiagram-VM6X3IG4-BylmIGSg.js → wardleyDiagram-VM6X3IG4-CjrkKWUR.js} +1 -1
  617. package/studio/web/assets/{workers-C0bFIedw.js → workers-pR3jRY9D.js} +1 -1
  618. package/studio/web/assets/x-DIzaLEdK.js +1 -0
  619. package/studio/web/assets/{xml-HWd01lU-.js → xml-2iRnMhQO.js} +1 -1
  620. package/studio/web/assets/{xychartDiagram-S5SC5T6Z-CoKALMXr.js → xychartDiagram-S5SC5T6Z-Biok4GYV.js} +1 -1
  621. package/studio/web/assets/{yaml-CIH0Nt-h.js → yaml-Bf92gJpd.js} +1 -1
  622. package/studio/web/index.html +14 -14
  623. package/upgrade/directives/5-3-0.ts +132 -0
  624. package/upgrade/directives/directivesController.ts +2 -1
  625. package/utility/OperationFunctionCaller.ts +2 -1
  626. package/utility/common_utils.ts +30 -5
  627. package/utility/componentNames.ts +12 -0
  628. package/utility/environment/environmentManager.ts +3 -7
  629. package/utility/environment/systemInformation.ts +7 -0
  630. package/utility/errors/commonErrors.ts +4 -0
  631. package/utility/errors/hdbError.ts +29 -0
  632. package/utility/hdbTerms.ts +17 -0
  633. package/utility/logging/harper_logger.ts +87 -14
  634. package/utility/logging/logRotator.ts +72 -45
  635. package/utility/nodeIdentity.ts +45 -0
  636. package/utility/npmUtilities.ts +10 -8
  637. package/utility/operationPermissions.ts +18 -1
  638. package/utility/operation_authorization.ts +231 -42
  639. package/utility/watchPath.ts +63 -0
  640. package/utility/watcherFallback.ts +270 -0
  641. package/validation/configValidator.ts +209 -72
  642. package/validation/installValidator.ts +15 -0
  643. package/validation/validationWrapper.ts +18 -4
  644. package/studio/web/assets/Chat-JpO8EtUu.js +0 -2067
  645. package/studio/web/assets/FloatingChat-Bcj3xSZu.js +0 -23
  646. package/studio/web/assets/applications-ByqLRKyZ.js +0 -296
  647. package/studio/web/assets/architecture-7GRP2DOG-DNdx5tEU.js +0 -1
  648. package/studio/web/assets/authStore-qKmCZcaf.js +0 -3
  649. package/studio/web/assets/channel-DtCV8PTL.js +0 -1
  650. package/studio/web/assets/chunk-R7TYR2AO-Irip67yr.js +0 -10
  651. package/studio/web/assets/classDiagram-DTDB5LWJ-DbO_dCNE.js +0 -1
  652. package/studio/web/assets/classDiagram-v2-JRS7N3AN-DbO_dCNE.js +0 -1
  653. package/studio/web/assets/eventmodeling-NTZA5JFV-5jbe4A5P.js +0 -1
  654. package/studio/web/assets/flowDiagram-A5DVABFB-Dp9Ezlow.js +0 -1
  655. package/studio/web/assets/index-aSt5tY-L.js +0 -824
  656. package/studio/web/assets/index.lazy-B9jiPwT8.js +0 -2
  657. package/studio/web/assets/notifications-CUoYgU98.js +0 -1
  658. package/studio/web/assets/railroad-abnf-HS5TGJTU-Bc0Qi0WH.js +0 -1
  659. package/studio/web/assets/railroad-ebnf-LZEXJU2U-G8rVVZ2C.js +0 -1
  660. package/studio/web/assets/railroad-peg-WCYAUIDC-CrehKBhC.js +0 -1
  661. package/studio/web/assets/stateDiagram-v2-4QOOHH4V-D4tuw9Su.js +0 -1
  662. package/studio/web/assets/status-D7Xn5ePA.js +0 -61
  663. package/studio/web/assets/swimlanesDiagram-VK2B7HYN-XOhmNEvq.js +0 -8
  664. package/studio/web/assets/vendor-core-RCcadM3e.js +0 -73
  665. package/studio/web/assets/vendor-datadog-BRv-mOv1.js +0 -6
  666. package/studio/web/assets/vendor-tanstack-BiFWSB3W.js +0 -1
  667. package/studio/web/assets/x-B9o9hsep.js +0 -1
  668. /package/studio/web/assets/{sizeCapture-X5ZJPWSS-B0uUizjq.js → sizeCapture-INFHLROL-B0uUizjq.js} +0 -0
@@ -132,16 +132,66 @@ export function shouldAbortSlowReplay(totalElapsedMs: number, timeLimitMs = REPL
132
132
  }
133
133
 
134
134
  /**
135
- * Wraps a transaction-log query iterator so a corrupt/torn frame ends that log's iteration
136
- * cleanly instead of escaping as an uncaughtException. rocksdb-js throws a bounded RangeError
137
- * when an entry's framing is broken; framing loss means the next entry can't be located, so the
138
- * frame marks end-of-log (entries before it were already yielded) and startup replay /
139
- * replication broadcast continue. `onCorruptFrame` fires once, latched — kept a callback (not a
140
- * direct log) so this module stays out of the Harper module graph and is unit-testable.
135
+ * A corrupt transaction-log frame from rocksdb-js. `resyncPosition` is set only when intact entries
136
+ * follow the break, which is what distinguishes lost entries from a merely truncated tail; its
137
+ * absence is also all that any rocksdb-js predating that field can report.
138
+ */
139
+ export type CorruptFrameError = RangeError & {
140
+ logId?: number | null;
141
+ position?: number | null;
142
+ resyncPosition?: number | null;
143
+ unreadableBytes?: number | null;
144
+ };
145
+
146
+ /**
147
+ * Corrupt frames hit by one `getRange` call, shared by its per-log iterators.
148
+ *
149
+ * `truncatedVersions` is what a consumer has to act on: a break destroys the framing after the last
150
+ * entry the broken log yielded, and whether the entries it swallowed continued that entry's version
151
+ * is exactly what can no longer be read — UNLESS that last entry's own `endTxn` already closed its
152
+ * transaction, in which case nothing of it was left open to swallow. That version's transaction is
153
+ * therefore incomplete only when it wasn't already known-closed, and replay must discard it rather
154
+ * than commit the part of it that was still readable. A log that broke before yielding anything
155
+ * truncates no transaction.
156
+ *
157
+ * `midLogBreak` is coarser: true once any break in this range left intact entries unreadable behind
158
+ * it (see {@link isMidLogBreak}), regardless of which version they belonged to. A consumer that must
159
+ * never serve a range with lost entries — an elected branch replay publishing itself as a trustworthy
160
+ * point-in-time copy — rejects on this rather than on `truncatedVersions`, since a mid-log break can
161
+ * strand entries whose version this range never even attributes to one log (harper#2016, #2063).
162
+ */
163
+ export interface CorruptFrameStop {
164
+ breaks: number;
165
+ truncatedVersions: Set<number>;
166
+ midLogBreak: boolean;
167
+ }
168
+
169
+ /**
170
+ * Whether a corrupt frame is a mid-log break — intact entries followed it, so entries were lost
171
+ * rather than the log merely being torn at its tail. Shared by the reporter below and by
172
+ * `RocksTransactionLogStore.getRange`'s `CorruptFrameStop.midLogBreak`, so the two can't drift on
173
+ * what counts as a mid-log break.
174
+ */
175
+ export function isMidLogBreak(error: CorruptFrameError): boolean {
176
+ return error.resyncPosition != null;
177
+ }
178
+
179
+ /**
180
+ * Wraps a transaction-log query iterator so a corrupt/torn frame ends that log's iteration cleanly
181
+ * instead of escaping as an uncaughtException.
182
+ *
183
+ * Iteration stops at the break whether or not intact entries follow it. Resuming past a mid-log
184
+ * break would recover those entries, but a transaction log carries no frame-level transaction
185
+ * boundaries: replay groups equal-version entries into one source transaction, so skipping a frame
186
+ * inside such a group applies and checkpoints the surviving subset of a transaction that never
187
+ * committed that way at the source. Availability loss is visible and recoverable; a silently torn
188
+ * transaction is neither. Recovery is deferred until the engine can resume at a proven boundary
189
+ * (harper#2016, harper#2063); `resyncPosition` is used only to report the break as lost entries
190
+ * rather than as a truncated tail.
141
191
  */
142
192
  export function endIteratorOnCorruptFrame<T>(
143
193
  iterator: Iterator<T>,
144
- onCorruptFrame: (error: RangeError) => void
194
+ onCorruptFrame: (error: CorruptFrameError) => void
145
195
  ): IterableIterator<T> {
146
196
  let stopped = false;
147
197
  return {
@@ -157,7 +207,7 @@ export function endIteratorOnCorruptFrame<T>(
157
207
  // version-dependent (1.4.2 added hex offsets). Anything else re-throws.
158
208
  if (!(error instanceof RangeError)) throw error;
159
209
  stopped = true;
160
- onCorruptFrame(error);
210
+ onCorruptFrame(error as CorruptFrameError);
161
211
  return { done: true, value: undefined };
162
212
  }
163
213
  },
@@ -175,3 +225,116 @@ export function endIteratorOnCorruptFrame<T>(
175
225
  },
176
226
  };
177
227
  }
228
+
229
+ /**
230
+ * A corrupt frame, accumulated for the life of the process. The same frame is re-encountered by
231
+ * every reader until each consumer's resume cursor has passed it, so this is deduplicated by
232
+ * location and the repeats become a count.
233
+ */
234
+ export interface CorruptFrameReport {
235
+ log: string;
236
+ logId?: number;
237
+ position?: number;
238
+ /** Intact entries followed the break, so entries were lost rather than merely truncated. */
239
+ midLog: boolean;
240
+ /** Extent of the unreadable region, when the engine reports it; 0 when nothing valid follows it. */
241
+ unreadableBytes: number;
242
+ firstSeen: number;
243
+ lastSeen: number;
244
+ occurrences: number;
245
+ }
246
+
247
+ /** Distinct break sites retained. One physical corruption yields one site, so this is generous. */
248
+ export const MAX_CORRUPT_FRAME_REPORTS = 256;
249
+
250
+ // Re-encounters move a site to the end, so the first key is the least recently seen. Full means
251
+ // evicting that one rather than refusing a new site, which could not then be deduplicated.
252
+ const corruptFrameReports = new Map<string, CorruptFrameReport>();
253
+ let evictedCorruptFrameReports = 0;
254
+
255
+ /**
256
+ * Every corrupt frame seen by this worker. This is not yet consumed by cluster/health status;
257
+ * callers must aggregate it across worker threads before exposing a node-wide signal.
258
+ *
259
+ * Mid-log breaks are immediately logged at error level even without that consumer.
260
+ */
261
+ export function getCorruptFrameReports(): CorruptFrameReport[] {
262
+ return [...corruptFrameReports.values()];
263
+ }
264
+
265
+ /** Break sites evicted because {@link MAX_CORRUPT_FRAME_REPORTS} was reached. */
266
+ export function getEvictedCorruptFrameReportCount(): number {
267
+ return evictedCorruptFrameReports;
268
+ }
269
+
270
+ export function clearCorruptFrameReports() {
271
+ corruptFrameReports.clear();
272
+ evictedCorruptFrameReports = 0;
273
+ }
274
+
275
+ // `logId`/`position` are absent on any rocksdb-js predating the resync support, and every break on
276
+ // a stream would then collapse onto one key — folding genuinely different corruptions into a single
277
+ // count that only ever logs once. The message carries the offset and file in text, so it separates
278
+ // them when the fields can't.
279
+ function corruptFrameKey(logName: string, error: CorruptFrameError): string {
280
+ const { logId, position } = error;
281
+ return logId != null && position != null
282
+ ? `${logName}\u0000${logId}:${position}`
283
+ : `${logName}\u0000${error.message}`;
284
+ }
285
+
286
+ /**
287
+ * Records a corrupt frame and logs it once per distinct break.
288
+ *
289
+ * A mid-log break is an `error`, not a `warn`: entries after it were acknowledged and are now
290
+ * quarantined behind it. Severity follows the break's own shape, never this pass's outcome — every
291
+ * pass stops, so keying on that would report the #2063 signature with the benign torn-tail `warn`.
292
+ * A site first seen as a torn tail can escalate later, since only a rocksdb-js that reports
293
+ * `resyncPosition` can tell the two apart.
294
+ */
295
+ export function createCorruptFrameReporter(logger: {
296
+ warn: (message: string, error?: unknown) => void;
297
+ error: (message: string, error?: unknown) => void;
298
+ }) {
299
+ return (logName: string) => (error: CorruptFrameError) => {
300
+ const midLog = isMidLogBreak(error);
301
+ const unreadableBytes = error.unreadableBytes ?? 0;
302
+ const now = Date.now();
303
+ const key = corruptFrameKey(logName, error);
304
+ const existing = corruptFrameReports.get(key);
305
+ if (existing) {
306
+ corruptFrameReports.delete(key);
307
+ corruptFrameReports.set(key, existing);
308
+ existing.occurrences++;
309
+ existing.lastSeen = now;
310
+ if (!midLog || existing.midLog) return;
311
+ existing.midLog = true;
312
+ existing.unreadableBytes = unreadableBytes;
313
+ } else {
314
+ if (corruptFrameReports.size >= MAX_CORRUPT_FRAME_REPORTS) {
315
+ corruptFrameReports.delete(corruptFrameReports.keys().next().value);
316
+ evictedCorruptFrameReports++;
317
+ }
318
+ corruptFrameReports.set(key, {
319
+ log: logName,
320
+ logId: error.logId ?? undefined,
321
+ position: error.position ?? undefined,
322
+ midLog,
323
+ unreadableBytes,
324
+ firstSeen: now,
325
+ lastSeen: now,
326
+ occurrences: 1,
327
+ });
328
+ }
329
+ if (midLog) {
330
+ logger.error(
331
+ `Corrupt entry in transaction log "${logName}"; ${unreadableBytes} byte(s) are unreadable and the entries within them are lost. ` +
332
+ 'Intact entries follow the break, but reading stops there rather than skipping the frame, which could tear a source transaction: ' +
333
+ 'they are quarantined until the log is repaired or this node is re-cloned, and they are neither replayed nor replicated meanwhile.',
334
+ error
335
+ );
336
+ } else {
337
+ logger.warn(`Stopping transaction log "${logName}" at a corrupt entry during replay`, error);
338
+ }
339
+ };
340
+ }
@@ -1,11 +1,12 @@
1
1
  import { ClientError, IndexRebuildingError, Violation } from '../utility/errors/hdbError.ts';
2
2
  import { OVERFLOW_MARKER, MAX_SEARCH_KEY_LENGTH, SEARCH_TYPES } from '../utility/lmdb/terms.ts';
3
3
  import { compareKeys, MAXIMUM_KEY, writeKey } from 'ordered-binary';
4
- import { SKIP } from '@harperfast/extended-iterable';
4
+ import { SKIP, ExtendedIterable } from '@harperfast/extended-iterable';
5
5
  import { INVALIDATED, EVICTED, freezeRecord } from './Table.ts';
6
6
  import type { DirectCondition, Id } from './ResourceInterface.ts';
7
7
  import { RequestTarget } from './RequestTarget.ts';
8
8
  import { lastMetadata } from './RecordEncoder.ts';
9
+ import { writeKeyId } from './DatabaseTransaction.ts';
9
10
  import { recordAction } from './analytics/write';
10
11
  import { RocksDatabase } from '@harperfast/rocksdb-js';
11
12
 
@@ -232,6 +233,41 @@ function composeRecordFilter(recordFilters, table, context): (primaryKey: Id) =>
232
233
  };
233
234
  }
234
235
 
236
+ /**
237
+ * A record's index entries are not adjacent — the composite `[indexedValue, primaryKey]` key sorts
238
+ * on the indexed value first — so comparing neighbours cannot collapse them and the scan has to
239
+ * remember what it already yielded (#2434).
240
+ *
241
+ * Heap cost is one key per distinct record in the scanned range, held for the life of the scan, and
242
+ * a page window does not cap it: sibling-condition and row filters run downstream, so a selective
243
+ * filter keeps the scan running and the set growing while the page fills. On a multi-million-row
244
+ * range that is hundreds of MB where main streamed at O(1). Accepted for #2434 over the bounded
245
+ * alternative, which costs a primary read per index entry.
246
+ */
247
+ function distinctRecords(entries: any): AsyncIterable<Id> {
248
+ const distinct = new ExtendedIterable();
249
+ (distinct as any).iterate = (options) => {
250
+ // A non-scalar key decodes to a fresh instance per entry, so identity never matches it;
251
+ // `writeKeyId` is the store's own key equality. Its bytes get their own set because a scalar
252
+ // string id can legitimately carry exactly those bytes, and one set would fold the two —
253
+ // the collision `flattenKey` has, and the reason Table.ts prefixes its key ids.
254
+ const yieldedKeys = new Set();
255
+ const yieldedEncodedKeys = new Set();
256
+ // map rather than filter: filter clears `continueOnRecoverableError` for everything below it
257
+ return entries
258
+ .map((primaryKey) => {
259
+ const isEncoded = typeof primaryKey === 'object' && primaryKey !== null;
260
+ const yielded = isEncoded ? yieldedEncodedKeys : yieldedKeys;
261
+ const identity = isEncoded ? writeKeyId(primaryKey) : primaryKey;
262
+ if (yielded.has(identity)) return SKIP;
263
+ yielded.add(identity);
264
+ return primaryKey;
265
+ })
266
+ .iterate(options);
267
+ };
268
+ return distinct as any;
269
+ }
270
+
235
271
  /**
236
272
  * Search for records or keys, based on the search condition, using an index if available
237
273
  * @param searchCondition
@@ -261,6 +297,9 @@ export function searchByIndex(
261
297
  throw new ClientError(`Search condition for ${attribute_name} must have a value`);
262
298
  }
263
299
  let needFullScan;
300
+ // `[indexedValue, primaryKey]` is unique, so a scan that stays inside one indexed value cannot
301
+ // reach a record twice and skips the collapse below
302
+ let scansOneIndexedValue;
264
303
  if (Array.isArray(attribute_name)) {
265
304
  const firstAttributeName = attribute_name[0];
266
305
  // get the potential relationship attribute
@@ -388,6 +427,7 @@ export function searchByIndex(
388
427
  start = value;
389
428
  end = value;
390
429
  inclusiveEnd = true;
430
+ scansOneIndexedValue = true;
391
431
  break;
392
432
  case 'in':
393
433
  // Phase 1: route through filter — index-merge optimization is a Phase 2 follow-up.
@@ -531,7 +571,7 @@ export function searchByIndex(
531
571
  }
532
572
  return loaded;
533
573
  }
534
- return index.getRange(rangeOptions).map(
574
+ const scanned = index.getRange(rangeOptions).map(
535
575
  filter
536
576
  ? function ({ key, value }) {
537
577
  let recordMatcher: any;
@@ -554,6 +594,14 @@ export function searchByIndex(
554
594
  }
555
595
  : ({ value }) => value
556
596
  );
597
+ // Collapsing AFTER the map is required, not incidental: the condition's own filter tests one
598
+ // element at a time, so a record whose first entry fails it and whose second passes must
599
+ // still be reached. Collapsing first would settle that record on the failing entry and drop
600
+ // it. Scoped to attributes the schema declares multi-valued; a runtime array under an
601
+ // undeclared attribute repeats the same way but stays outside this boundary.
602
+ return scansOneIndexedValue || !findAttribute(Table.attributes, attribute_name)?.elements
603
+ ? scanned
604
+ : distinctRecords(scanned);
557
605
  } else {
558
606
  return Table.primaryStore
559
607
  .getRange(reverse ? { end: true, transaction, reverse: true } : { start: true, transaction })
@@ -1112,6 +1160,91 @@ export function filterByType(searchCondition, Table, context, filtered, isPrimar
1112
1160
  }
1113
1161
  }
1114
1162
 
1163
+ /**
1164
+ * Estimates a range comparator's entry count from the store's statistical estimate, blended with
1165
+ * the table-fraction heuristic by the estimate's confidence so low-confidence estimates degrade
1166
+ * to the old behavior. Returns undefined (caller falls back to the heuristic) when the store
1167
+ * cannot estimate, the shape is unexpected, or the executed range wouldn't match this one.
1168
+ */
1169
+ function estimateRangeCondition(table, condition, searchType, fraction) {
1170
+ const attributeName = condition[0] ?? condition.attribute;
1171
+ const isPrimaryKey = attributeName === table.primaryKey;
1172
+ const store = isPrimaryKey ? table.primaryStore : table.indices[attributeName];
1173
+ // LMDB-backed and custom index stores do not implement estimateCount
1174
+ if (typeof store?.estimateCount !== 'function') return undefined;
1175
+ let value = condition[1] ?? condition.value;
1176
+ if (value instanceof Date) value = value.getTime();
1177
+ let range;
1178
+ switch (searchType) {
1179
+ case 'lt':
1180
+ // `start: true` mirrors searchByIndex: `true` sorts above `null`, so an indexNulls
1181
+ // index's `[null, primaryKey]` entries are outside the executed range
1182
+ range = { start: true, end: value };
1183
+ break;
1184
+ case 'le':
1185
+ range = { start: true, end: value, inclusiveEnd: true };
1186
+ break;
1187
+ case 'gt':
1188
+ range = { start: value, exclusiveStart: true };
1189
+ break;
1190
+ case 'ge':
1191
+ range = { start: value };
1192
+ break;
1193
+ case 'between':
1194
+ case 'gele':
1195
+ case 'gelt':
1196
+ case 'gtlt':
1197
+ case 'gtle': {
1198
+ if (!Array.isArray(value)) return undefined;
1199
+ let [start, end] = value;
1200
+ if (start instanceof Date) start = start.getTime();
1201
+ if (end instanceof Date) end = end.getTime();
1202
+ range = {
1203
+ start,
1204
+ end,
1205
+ inclusiveEnd: searchType === 'between' || searchType === 'gele' || searchType === 'gtle',
1206
+ exclusiveStart: searchType === 'gtlt' || searchType === 'gtle',
1207
+ };
1208
+ break;
1209
+ }
1210
+ case 'starts_with': {
1211
+ const prefix = value?.toString();
1212
+ if (!prefix) return undefined;
1213
+ range = { start: prefix, end: getStringPrefixUpperBound(prefix) };
1214
+ break;
1215
+ }
1216
+ case 'prefix': {
1217
+ let start = Array.isArray(value) ? value : [value, null];
1218
+ if (start[start.length - 1] != null) start = start.concat(null);
1219
+ const end = start.slice(0);
1220
+ end[end.length - 1] = MAXIMUM_KEY;
1221
+ range = { start, end };
1222
+ break;
1223
+ }
1224
+ default:
1225
+ return undefined;
1226
+ }
1227
+ // Long string bounds get truncated + filtered at execution (searchByIndex), so the
1228
+ // executed range is wider than this one; don't estimate what won't be iterated.
1229
+ if (
1230
+ (typeof range.start === 'string' && range.start.length > MAX_SEARCH_KEY_LENGTH) ||
1231
+ (typeof range.end === 'string' && range.end.length > MAX_SEARCH_KEY_LENGTH)
1232
+ ) {
1233
+ return undefined;
1234
+ }
1235
+ let count, confidence;
1236
+ try {
1237
+ ({ count, confidence } = store.estimateCount(range) ?? {});
1238
+ } catch {
1239
+ // a concurrently closing/dropped store must degrade the plan, not fail the query
1240
+ return undefined;
1241
+ }
1242
+ if (!Number.isFinite(count) || count < 0 || !Number.isFinite(confidence) || confidence < 0 || confidence > 1)
1243
+ return undefined;
1244
+ const heuristic = fraction * estimatedEntryCount(table.primaryStore) + 1;
1245
+ return Math.max(1, Math.round(confidence * count + (1 - confidence) * heuristic));
1246
+ }
1247
+
1115
1248
  export function estimateCondition(table) {
1116
1249
  function estimateConditionForTable(condition) {
1117
1250
  if (condition.estimated_count === undefined) {
@@ -1141,7 +1274,14 @@ export function estimateCondition(table) {
1141
1274
  // skip if it is cached
1142
1275
  let searchType = condition.comparator || condition.search_type;
1143
1276
  searchType = ALTERNATE_COMPARATOR_NAMES[searchType] || searchType;
1144
- if (searchType === SEARCH_TYPES.EQUALS || !searchType) {
1277
+ if (condition.negated) {
1278
+ // a negated condition always executes as a full scan (searchByIndex forces
1279
+ // needFullScan), so follow the filter-only convention used by contains/ends_with:
1280
+ // estimate Infinity so its positive-range estimate can never win the driving-condition
1281
+ // ordering. Short-circuit here rather than computing (and discarding) a positive-range
1282
+ // estimate that would cross the native FFI boundary for nothing.
1283
+ condition.estimated_count = Infinity;
1284
+ } else if (searchType === SEARCH_TYPES.EQUALS || !searchType) {
1145
1285
  const attribute_name = condition[0] ?? condition.attribute;
1146
1286
  if (attribute_name == null || attribute_name === table.primaryKey) condition.estimated_count = 1;
1147
1287
  else if (Array.isArray(attribute_name) && attribute_name.length > 1) {
@@ -1192,11 +1332,14 @@ export function estimateCondition(table) {
1192
1332
  } else if (Array.isArray(condition.value)) {
1193
1333
  condition.estimated_count = Infinity;
1194
1334
  } else condition.estimated_count = Infinity;
1195
- // for range queries (betweens, startsWith, greater, etc.), just arbitrarily guess
1196
1335
  } else if (searchType === 'starts_with' || searchType === 'prefix')
1197
- condition.estimated_count = STARTS_WITH_ESTIMATE * estimatedEntryCount(table.primaryStore) + 1;
1336
+ condition.estimated_count =
1337
+ estimateRangeCondition(table, condition, searchType, STARTS_WITH_ESTIMATE) ??
1338
+ STARTS_WITH_ESTIMATE * estimatedEntryCount(table.primaryStore) + 1;
1198
1339
  else if (searchType === 'between')
1199
- condition.estimated_count = BETWEEN_ESTIMATE * estimatedEntryCount(table.primaryStore) + 1;
1340
+ condition.estimated_count =
1341
+ estimateRangeCondition(table, condition, searchType, BETWEEN_ESTIMATE) ??
1342
+ BETWEEN_ESTIMATE * estimatedEntryCount(table.primaryStore) + 1;
1200
1343
  else if (searchType === 'sort') {
1201
1344
  const attribute_name = condition[0] ?? condition.attribute;
1202
1345
  const index = table.indices[attribute_name];
@@ -1211,7 +1354,10 @@ export function estimateCondition(table) {
1211
1354
  if (index?.customIndex?.estimateCount)
1212
1355
  // allow custom index to define its own estimation of counts
1213
1356
  condition.estimated_count = index.customIndex.estimateCount(condition.value);
1214
- else condition.estimated_count = OPEN_RANGE_ESTIMATE * estimatedEntryCount(table.primaryStore) + 1;
1357
+ else
1358
+ condition.estimated_count =
1359
+ estimateRangeCondition(table, condition, searchType, OPEN_RANGE_ESTIMATE) ??
1360
+ OPEN_RANGE_ESTIMATE * estimatedEntryCount(table.primaryStore) + 1;
1215
1361
  }
1216
1362
  // we give a condition significantly more weight/preference if we will be ordering by it
1217
1363
  if (typeof condition.descending === 'boolean') condition.estimated_count /= 2;
@@ -1397,6 +1543,7 @@ function parseBlock(query, expectedEnd) {
1397
1543
  break;
1398
1544
  case 'group-by':
1399
1545
  recordError('group by is not implemented yet');
1546
+ break;
1400
1547
  case 'sort':
1401
1548
  query.sort = toSortObject(args);
1402
1549
  break;
@@ -95,7 +95,7 @@ export function addSubscription(table, key, listener?: (key) => any, startTime?:
95
95
  * subscription and get the initial state.
96
96
  */
97
97
  class Subscription extends IterableEventQueue {
98
- listener: (recordId: Id, auditEntry: any, localTime: number, beginTxn: boolean) => void;
98
+ listener: (recordId: Id, auditEntry: any, txnLogKey: number, beginTxn: boolean) => void;
99
99
  subscriptions: any;
100
100
  startTime?: number;
101
101
  includeDescendants?: boolean;
@@ -178,10 +178,10 @@ function notifyFromTransactionData(subscriptions, auditLogIterable?, allowYield
178
178
  }
179
179
  if (result.done) break;
180
180
  const auditRecord = result.value;
181
- const timestamp: number = auditRecord.localTime ?? auditRecord.version;
181
+ const timestamp: number = auditRecord.txnLogKey;
182
182
  subscriptions.lastTxnTime = timestamp;
183
183
  // the transaction extent: RocksDB entries committed together share the log key (record
184
- // versions may differ); LMDB's localTime is a per-entry audit key, so version delimits there
184
+ // versions may differ); LMDB's transaction-log key is per-entry, so version delimits there
185
185
  const txnKey = auditStore.reusableIterable ? timestamp : auditRecord.version;
186
186
  if (ACTIONS_OF_INTEREST.includes(auditRecord.type)) {
187
187
  const tableSubscriptions = subscriptions[auditRecord.tableId];
package/security/auth.ts CHANGED
@@ -7,13 +7,21 @@ import { v4 as uuid } from 'uuid';
7
7
  import * as env from '../utility/environment/environmentManager.ts';
8
8
  import { CONFIG_PARAMS, AUTH_AUDIT_STATUS, AUTH_AUDIT_TYPES } from '../utility/hdbTerms.ts';
9
9
  import harperLogger from '../utility/logging/harper_logger.ts';
10
- const { forComponent, AuthAuditLog } = harperLogger;
10
+ const { forComponent, AuthAuditLog, errorForLog } = harperLogger;
11
11
  import serverHandlers from '../server/itc/serverHandlers.js';
12
12
  const { user } = serverHandlers;
13
- import { Headers, addVaryHeader } from '../server/serverHelpers/Headers.ts';
13
+ import { Headers, addVaryHeader, SHARED_CACHE_OPTIN, PRIVATE_SCOPE } from '../server/serverHelpers/Headers.ts';
14
14
  import { convertToMS } from '../utility/common_utils.ts';
15
15
  import { verifyCertificate } from './certificateVerification/index.ts';
16
+ import {
17
+ credentialRejectionError,
18
+ deferCredentialRejection,
19
+ getDeferredCredentialRejection,
20
+ isCredentialRejection,
21
+ } from './deferredAuthentication.ts';
16
22
  import { serializeMessage } from '../server/serverHelpers/contentTypes.ts';
23
+ import { hdbErrors } from '../utility/errors/hdbError.ts';
24
+ const { AUTHENTICATION_ERROR_MSGS, HTTP_STATUS_CODES } = hdbErrors;
17
25
  const authLogger = forComponent('authentication');
18
26
  const { debug } = authLogger;
19
27
  const authEventLog = authLogger.withTag('auth-event');
@@ -50,10 +58,6 @@ const LOG_AUTH_FAILED = env.get(CONFIG_PARAMS.LOGGING_AUDITAUTHEVENTS_LOGFAILED)
50
58
 
51
59
  const DEFAULT_COOKIE_EXPIRES = 'Tue, 01 Oct 8307 19:33:20 GMT';
52
60
 
53
- // RFC 9111 cache-scope directives; boundaries on both sides so a token like `public-foo` doesn't match
54
- const SHARED_CACHE_OPTIN = /(^|[,\s])(public|s-maxage)($|[\s,;=])/i;
55
- const PRIVATE_SCOPE = /(^|[,\s])(private|no-store)($|[\s,;=])/i;
56
-
57
61
  let authorizationCache = new Map();
58
62
  server.onInvalidatedUser(() => {
59
63
  // TODO: Eventually we probably want to be able to invalidate individual users
@@ -190,7 +194,13 @@ export async function authentication(request, nextHandler) {
190
194
  if (request.user) {
191
195
  // already authenticated
192
196
  } else if (authorization) {
193
- const cachedUser = authorizationCache.get(authorization);
197
+ let cachedUser = authorizationCache.get(authorization);
198
+ // A cached Bearer identity must not outlive its token: expiry is the only revocation
199
+ // mechanism for scoped tokens, so it has to be exact, not cache-TTL-fuzzy.
200
+ if (cachedUser?.authExpiresAt && cachedUser.authExpiresAt * 1000 <= Date.now()) {
201
+ authorizationCache.delete(authorization);
202
+ cachedUser = undefined;
203
+ }
194
204
  if (cachedUser?.role) {
195
205
  // Shallow-clone so verifyPerms's `role.permission = fullRolePerms` reassignment
196
206
  // doesn't mutate the cache entry (defense-in-depth; operations and other
@@ -204,6 +214,7 @@ export async function authentication(request, nextHandler) {
204
214
  const strategy = authorization.slice(0, spaceIndex);
205
215
  const credentials = authorization.slice(spaceIndex + 1);
206
216
  let username, password;
217
+ let credentialRejection;
207
218
  try {
208
219
  switch (strategy) {
209
220
  case 'Basic':
@@ -231,12 +242,23 @@ export async function authentication(request, nextHandler) {
231
242
  // API has its own logic for handling this
232
243
  status: -1,
233
244
  });
234
- } catch {
245
+ } catch (refreshError) {
246
+ // Preserve refresh-validation faults; only a tagged rejection permits falling
247
+ // back to the original operation-token rejection.
248
+ if (!isCredentialRejection(refreshError)) throw refreshError;
235
249
  throw error;
236
250
  }
237
251
  }
252
+ // A non-'invalid token' rejection (e.g. expired) must propagate, not fall
253
+ // through to caching an undefined user (which would read as anonymous).
254
+ throw error;
238
255
  }
239
256
  break;
257
+ default:
258
+ throw credentialRejectionError(
259
+ AUTHENTICATION_ERROR_MSGS.GENERIC_AUTH_FAIL,
260
+ HTTP_STATUS_CODES.UNAUTHORIZED
261
+ );
240
262
  }
241
263
  } catch (err) {
242
264
  if (LOG_AUTH_FAILED) {
@@ -247,18 +269,31 @@ export async function authentication(request, nextHandler) {
247
269
  }
248
270
  }
249
271
 
250
- return applyResponseHeaders({
251
- status: 401,
252
- body: serializeMessage({ error: err.message }, request),
253
- });
272
+ const internalFault = !isCredentialRejection(err);
273
+ if (request.isOperationsServer || internalFault) {
274
+ if (internalFault) authLogger.error('Authentication failed internally', errorForLog(err));
275
+ return applyResponseHeaders({
276
+ status: 401,
277
+ body: serializeMessage(
278
+ { error: internalFault ? AUTHENTICATION_ERROR_MSGS.GENERIC_AUTH_FAIL : err.message },
279
+ request
280
+ ),
281
+ });
282
+ }
283
+ credentialRejection = err;
254
284
  }
255
285
 
256
- authorizationCache.set(authorization, newUser);
257
- if (LOG_AUTH_SUCCESSFUL) authAuditLog(newUser.username, AUTH_AUDIT_STATUS.SUCCESS, strategy);
258
- // Shallow-clone so verifyPerms's `role.permission = fullRolePerms` reassignment
259
- // doesn't mutate the just-stored cache entry (defense-in-depth).
260
- if (newUser?.role) {
261
- newUser = { ...newUser, role: { ...newUser.role, permission: { ...newUser.role.permission } } };
286
+ if (credentialRejection) {
287
+ deferCredentialRejection(request, credentialRejection, strategy);
288
+ } else {
289
+ authorizationCache.set(authorization, newUser);
290
+ if (LOG_AUTH_SUCCESSFUL && newUser != null)
291
+ authAuditLog(newUser.username, AUTH_AUDIT_STATUS.SUCCESS, strategy);
292
+ // Shallow-clone so verifyPerms's `role.permission = fullRolePerms` reassignment
293
+ // doesn't mutate the just-stored cache entry (defense-in-depth).
294
+ if (newUser?.role) {
295
+ newUser = { ...newUser, role: { ...newUser.role, permission: { ...newUser.role.permission } } };
296
+ }
262
297
  }
263
298
  }
264
299
 
@@ -346,16 +381,19 @@ export async function authentication(request, nextHandler) {
346
381
  if (!response) return response;
347
382
  if (response.status === 401) {
348
383
  wasUnauthorized = true;
349
- if (
350
- headers['user-agent']?.startsWith('Mozilla') &&
351
- headers.accept?.startsWith('text/html') &&
352
- resources.loginPath
353
- ) {
354
- // on the web if we have a login page, default to redirecting to it
355
- response.status = 302;
356
- response.headers.set('Location', resources.loginPath(request));
357
- } // the HTTP specified way of indicating HTTP authentication methods supported:
358
- else response.headers.set('WWW-Authenticate', 'Basic');
384
+ // Downstream owns the challenge or redirect after Harper deferred the credential decision.
385
+ if (!getDeferredCredentialRejection(request)) {
386
+ if (
387
+ headers['user-agent']?.startsWith('Mozilla') &&
388
+ headers.accept?.startsWith('text/html') &&
389
+ resources.loginPath
390
+ ) {
391
+ // on the web if we have a login page, default to redirecting to it
392
+ response.status = 302;
393
+ response.headers.set('Location', resources.loginPath(request));
394
+ } // the HTTP specified way of indicating HTTP authentication methods supported:
395
+ else response.headers.set('WWW-Authenticate', 'Basic');
396
+ }
359
397
  }
360
398
  return applyResponseHeaders(response);
361
399
  } catch (error) {
@@ -367,7 +405,8 @@ export async function authentication(request, nextHandler) {
367
405
  // if we are rejecting the credentials (401, possibly rewritten to a login redirect); such a
368
406
  // response must never be stored by a shared cache and served to a different principal (#1565)
369
407
  const rejectedAuth = response?.status === 401 || wasUnauthorized;
370
- const identityDependent = !!request.user || rejectedAuth;
408
+ // A downstream response produced under the untouched credential remains identity-dependent (#1565).
409
+ const identityDependent = !!request.user || rejectedAuth || !!getDeferredCredentialRejection(request);
371
410
  // with CORS enabled the response is origin-dependent — ACAO reflects the request Origin, and
372
411
  // its absence when no Origin was sent is origin-dependent too — so a shared cache must
373
412
  // partition on Origin either way (#1518)