@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
@@ -41,6 +41,8 @@ import * as status from '../status/index.ts';
41
41
  import * as regDeprecated from '../../resources/registrationDeprecated.ts';
42
42
  import * as deploymentOperations from '../../components/deploymentOperations.ts';
43
43
  import * as secretOperations from '../../components/secretOperations.ts';
44
+ import * as trustPolicyOperations from '../../security/authn/oidc/trustPolicyOperations.ts';
45
+ import * as tokenExchange from '../../security/authn/oidc/tokenExchange.ts';
44
46
  import { contextStorage } from '../../resources/transaction.ts';
45
47
  import { isMainThread } from 'node:worker_threads';
46
48
  import {
@@ -49,6 +51,7 @@ import {
49
51
  setLocalOperationDispatch,
50
52
  } from './registeredOperations.ts';
51
53
  import { runWithOperationAuthorizationBypass } from './operationAuthorizationState.ts';
54
+ import { stripSuppliedParsedSqlObject } from './requestSanitization.ts';
52
55
 
53
56
  const pSearchSearch = util.promisify(search.search);
54
57
  let pEvaluateSql: (sql: string) => Promise<any>;
@@ -79,6 +82,42 @@ export type OperationFunctionName = ValueOf<typeof terms.OPERATIONS_ENUM>;
79
82
  * handles the response to the sender.
80
83
  */
81
84
  // TODO: Replace Function type with an actual function type (e.g. (): Thingy)
85
+ /**
86
+ * Fields stripped from an operation body before it reaches the operations log.
87
+ *
88
+ * `credentials` carries a transient token on deploy_component (`registryAuth` is its pre-rename
89
+ * name — still stripped, since this runs ahead of the validation that now rejects it). `value` /
90
+ * `values` carry .env secrets from set_env_value; `value` / `envelope` carry secrets from
91
+ * set_secret. `token` is the login-purpose token (login) and the CI identity token
92
+ * (exchange_oidc_token), and is also stripped defensively — no operation declares a top-level `token`,
93
+ * but validation allows unknown keys, so a mistyped `harper deploy setup token=…` must not log a live
94
+ * credential. `refresh_token` is the 30-day credential (refresh_operation_token).
95
+ *
96
+ * Redaction runs *before* the handler, so a rejected request logs a still-spendable credential —
97
+ * which is why a new secret-bearing field belongs here rather than left to the default (harper#1527
98
+ * was this same miss for set_env_value).
99
+ */
100
+ export const UNLOGGABLE_OPERATION_FIELDS = [
101
+ 'hdb_user',
102
+ 'hdbAuthHeader',
103
+ 'password',
104
+ 'payload',
105
+ 'credentials',
106
+ 'registryAuth',
107
+ 'value',
108
+ 'values',
109
+ 'envelope',
110
+ 'token',
111
+ 'refresh_token',
112
+ ];
113
+
114
+ /** Callers gate this on log level: it allocates, and the operations log is often off. */
115
+ export function redactForOperationLog(body: Record<string, any>): Record<string, any> {
116
+ const clean = { ...body };
117
+ for (const field of UNLOGGABLE_OPERATION_FIELDS) delete clean[field];
118
+ return clean;
119
+ }
120
+
82
121
  export async function processLocalTransaction(req: OperationRequest, operationFunction: Function) {
83
122
  try {
84
123
  if (
@@ -87,31 +126,7 @@ export async function processLocalTransaction(req: OperationRequest, operationFu
87
126
  harperLogger.logLevel === terms.LOG_LEVELS.DEBUG ||
88
127
  harperLogger.logLevel === terms.LOG_LEVELS.TRACE)
89
128
  ) {
90
- // Need to remove auth variables and secret-bearing fields, but we don't want to create
91
- // an object unless the logging is actually going to happen. credentials carries a
92
- // transient token on deploy_component (registryAuth is its pre-rename name — still
93
- // stripped, since this runs ahead of the validation that now rejects it, and a stale
94
- // caller's token must not reach the log); value/values carry .env secrets from
95
- // set_env_value; value/envelope carry secrets from set_secret — none may reach the
96
- // operations log. `token` is stripped defensively: no operation declares one at the top
97
- // level today, but validation allows unknown keys, so a caller that sends one anyway (a
98
- // mistyped `harper deploy setup token=…`) would otherwise log a live credential.
99
- /* eslint-disable no-unused-vars, @typescript-eslint/no-unused-vars */
100
- const {
101
- hdb_user,
102
- hdbAuthHeader,
103
- password,
104
- payload,
105
- credentials,
106
- registryAuth,
107
- value,
108
- values,
109
- envelope,
110
- token,
111
- ...cleanBody
112
- } = req.body;
113
- /* eslint-enable no-unused-vars, @typescript-eslint/no-unused-vars */
114
- operationLog.info(cleanBody);
129
+ operationLog.info(redactForOperationLog(req.body));
115
130
  }
116
131
  } catch (e) {
117
132
  operationLog.error(e);
@@ -172,6 +187,10 @@ export type OperationDefinition = {
172
187
  requiresSuperUser?: boolean;
173
188
  };
174
189
 
190
+ // Operation names this API installed a permission entry for, so a later registration that drops
191
+ // `requiresSuperUser` can retract exactly that entry and nothing else.
192
+ const declaredPermissionNames = new Set<string>();
193
+
175
194
  /**
176
195
  * Register an operation function with the server.
177
196
  * @param operationDefinition
@@ -181,7 +200,14 @@ server.registerOperation = (operationDefinition: OperationDefinition) => {
181
200
  if (isDeployValidating()) return;
182
201
  const { name, execute, requiresSuperUser } = operationDefinition;
183
202
  let handler = execute;
184
- if (requiresSuperUser !== undefined) {
203
+ if (requiresSuperUser === undefined) {
204
+ // A re-registration that drops the flag must also drop the entry the earlier one installed, or
205
+ // declaration and enforcement disagree: main retracts the grantable mark while this worker keeps
206
+ // honouring an already-persisted role grant. Scoped to names declared through this API, so one it
207
+ // never declared is untouched — a component that declared a built-in's name already overwrote
208
+ // that entry by declaring it, and this only follows.
209
+ if (declaredPermissionNames.delete(name)) opAuth.unregisterOperationPermission(name);
210
+ } else {
185
211
  // verifyPerms keys requiredPermissions by the handler's function `.name`, but registered ops
186
212
  // are typically anonymous arrows (all named "execute") which collide and can't be keyed. Wrap
187
213
  // in a FRESH function named after the op so the lookup resolves the right entry. Wrap rather
@@ -191,12 +217,14 @@ server.registerOperation = (operationDefinition: OperationDefinition) => {
191
217
  handler = (...args: any[]) => (execute as any)(...args);
192
218
  Object.defineProperty(handler, 'name', { value: name, configurable: true });
193
219
  opAuth.registerOperationPermission(name, { requiresSu: requiresSuperUser });
220
+ declaredPermissionNames.add(name);
194
221
  }
195
222
  OPERATION_FUNCTION_MAP.set(name as any, new OperationFunctionObject(handler));
196
223
  // Components load per-worker, so a registration made there is invisible to the main-thread
197
224
  // ops-API dispatcher (each thread has its own OPERATION_FUNCTION_MAP instance). Announce it
198
- // so the main thread can forward calls to this worker (#1736).
199
- if (!isMainThread) announceRegisteredOperation(name);
225
+ // so the main thread can forward calls here (#1736), and can mirror the role-allowlist mark that
226
+ // registerOperationPermission above made only in this thread's scope.
227
+ if (!isMainThread) announceRegisteredOperation(name, requiresSuperUser !== undefined);
200
228
  };
201
229
 
202
230
  // Register the durable MCP quota policy as a function (see components/mcp/quota.ts). Worker-local,
@@ -233,10 +261,30 @@ export function chooseOperation(json: OperationRequestBody, bypassAuth = false)
233
261
  if (json.operation === 'sql' || (json.search_operation && json.search_operation.operation === 'sql')) {
234
262
  const sql = require('../../sqlTranslator/index');
235
263
  const sqlStatement = json.operation === 'sql' ? json.sql : json.search_operation.sql;
264
+ // Before this dispatch's own parse is assigned, so a body-supplied object cannot survive it.
265
+ stripSuppliedParsedSqlObject(json);
236
266
  const parsedSqlObject = sql.convertSQLToAST(sqlStatement);
237
267
  json.parsed_sql_object = parsedSqlObject;
238
268
  if (!bypassAuth) {
239
- const astPermCheck = sql.checkASTPermissions(json, parsedSqlObject);
269
+ // The SQL path never reaches verifyPerms, so the role `operations` allowlist must be
270
+ // enforced here — otherwise an allowlisted role reaches unlisted operations via `sql`.
271
+ // json.operation is already the API name ('sql', or the outer job op like 'export_local').
272
+ const allowlistDenial = opAuth.verifyOperationsAllowlist(json, json.operation);
273
+ if (allowlistDenial) {
274
+ operationLog.error(`${HTTP_STATUS_CODES.FORBIDDEN} from operation ${json.operation}`);
275
+ operationLog.warn(`User '${json.hdb_user?.username}' is not permitted to ${json.operation}`);
276
+ throw handleHDBError(
277
+ new Error(),
278
+ allowlistDenial,
279
+ hdbErrors.HTTP_STATUS_CODES.FORBIDDEN,
280
+ undefined,
281
+ undefined,
282
+ true
283
+ );
284
+ }
285
+ // `json.operation` explicitly — the operation this dispatch already resolved, not a
286
+ // field read back off the request body.
287
+ const astPermCheck = sql.checkASTPermissions(json, parsedSqlObject, json.operation);
240
288
  if (astPermCheck) {
241
289
  operationLog.error(`${HTTP_STATUS_CODES.FORBIDDEN} from operation ${json.operation}`);
242
290
  operationLog.warn(`User '${json.hdb_user?.username}' is not permitted to ${json.operation}`);
@@ -255,7 +303,10 @@ export function chooseOperation(json: OperationRequestBody, bypassAuth = false)
255
303
  !bypassAuth &&
256
304
  json.operation !== terms.OPERATIONS_ENUM.CREATE_AUTHENTICATION_TOKENS &&
257
305
  json.operation !== terms.OPERATIONS_ENUM.LOGIN &&
258
- json.operation !== terms.OPERATIONS_ENUM.LOGOUT
306
+ json.operation !== terms.OPERATIONS_ENUM.LOGOUT &&
307
+ // Same rationale: the OIDC exchange authenticates its own caller (#2171), so there is no
308
+ // hdb_user for verifyPerms to check against.
309
+ json.operation !== terms.OPERATIONS_ENUM.EXCHANGE_OIDC_TOKEN
259
310
  ) {
260
311
  const functionToCheck = job_operation_function === undefined ? operation_function : job_operation_function;
261
312
  const operation_json = json.search_operation ? json.search_operation : json;
@@ -263,7 +314,12 @@ export function chooseOperation(json: OperationRequestBody, bypassAuth = false)
263
314
  operation_json.hdb_user = json.hdb_user;
264
315
  }
265
316
 
266
- const verifyPermsResult = opAuth.verifyPerms(operation_json, functionToCheck);
317
+ // Pass the top-level operation for the token-scope check: for an export job, operation_json
318
+ // is the nested search_operation, so json.operation (export_local/export_to_s3) is the op the
319
+ // scope must gate — not the inner search.
320
+ const verifyPermsResult = opAuth.verifyPerms(operation_json, functionToCheck, {
321
+ apiOperation: json.operation,
322
+ });
267
323
 
268
324
  if (verifyPermsResult) {
269
325
  operationLog.error(`${HTTP_STATUS_CODES.FORBIDDEN} from operation ${json.operation}`);
@@ -357,6 +413,9 @@ async function catchup(req: CatchupOperationRequest) {
357
413
  case terms.OPERATIONS_ENUM.UPSERT:
358
414
  await insert.upsert(transaction);
359
415
  break;
416
+ case terms.OPERATIONS_ENUM.PUT:
417
+ await insert.put(transaction);
418
+ break;
360
419
  case terms.OPERATIONS_ENUM.DELETE:
361
420
  await delete_.deleteRecord(transaction);
362
421
  break;
@@ -411,6 +470,7 @@ function initializeOperationFunctionMap(): Map<OperationFunctionName, OperationF
411
470
  opFuncMap.set(terms.OPERATIONS_ENUM.INSERT, new OperationFunctionObject(insert.insert));
412
471
  opFuncMap.set(terms.OPERATIONS_ENUM.UPDATE, new OperationFunctionObject(insert.update));
413
472
  opFuncMap.set(terms.OPERATIONS_ENUM.UPSERT, new OperationFunctionObject(insert.upsert));
473
+ opFuncMap.set(terms.OPERATIONS_ENUM.PUT, new OperationFunctionObject(insert.put));
414
474
  opFuncMap.set(terms.OPERATIONS_ENUM.SEARCH_BY_CONDITIONS, new OperationFunctionObject(search.searchByConditions));
415
475
  opFuncMap.set(terms.OPERATIONS_ENUM.SEARCH_BY_HASH, new OperationFunctionObject(search.searchByHash));
416
476
  opFuncMap.set(terms.OPERATIONS_ENUM.SEARCH_BY_ID, new OperationFunctionObject(search.searchByHash));
@@ -581,6 +641,19 @@ function initializeOperationFunctionMap(): Map<OperationFunctionName, OperationF
581
641
  terms.OPERATIONS_ENUM.GET_SECRETS_PUBLIC_KEY,
582
642
  new OperationFunctionObject(secretOperations.getSecretsPublicKey)
583
643
  );
644
+ opFuncMap.set(terms.OPERATIONS_ENUM.ADD_OIDC_TRUST, new OperationFunctionObject(trustPolicyOperations.addOidcTrust));
645
+ opFuncMap.set(
646
+ terms.OPERATIONS_ENUM.LIST_OIDC_TRUST,
647
+ new OperationFunctionObject(trustPolicyOperations.listOidcTrust)
648
+ );
649
+ opFuncMap.set(
650
+ terms.OPERATIONS_ENUM.DROP_OIDC_TRUST,
651
+ new OperationFunctionObject(trustPolicyOperations.dropOidcTrust)
652
+ );
653
+ opFuncMap.set(
654
+ terms.OPERATIONS_ENUM.EXCHANGE_OIDC_TOKEN,
655
+ new OperationFunctionObject(tokenExchange.exchangeOidcToken)
656
+ );
584
657
  opFuncMap.set(
585
658
  terms.OPERATIONS_ENUM.READ_TRANSACTION_LOG,
586
659
  new OperationFunctionObject(transactionLog.readTransactionLog)
@@ -0,0 +1,307 @@
1
+ import { serializeMessage, getMessageSerializer } from './contentTypes.ts';
2
+ import { logger } from '../../utility/logging/logger.ts';
3
+
4
+ /**
5
+ * The encoding work that every subscriber of a topic would otherwise redo for the same message.
6
+ * `payload` is the serialized message body; `frames` holds fully encoded protocol frames that are
7
+ * byte-identical across subscribers (MQTT QoS 0 PUBLISH packets), keyed by whatever the frame
8
+ * still varies on. `next` chains the encodings for any further content types the same message was
9
+ * delivered in — a chain rather than a map because a topic's subscribers realistically negotiate
10
+ * one or two content types, and this keeps the single-content-type case to one allocation.
11
+ *
12
+ * `hits` counts the subscribers after the first, so a caller can skip caching anything derived
13
+ * from the payload until a fan-out is known to exist. `failed` is a distinct state from an
14
+ * undefined `payload`, which a serializer can legitimately return (JSON of `undefined`).
15
+ * `bytes` is everything this entry holds — payload plus frames — and `epoch` records which
16
+ * generation those bytes are charged to, so work that lands after a rotation (a serialization that
17
+ * resolves late) is not charged to a budget it does not belong to, and a promotion re-charges the
18
+ * entry exactly once. That is what makes the budget an actual accounting rather than an estimate.
19
+ */
20
+ export interface SharedMessageEncoding {
21
+ serializer: Function;
22
+ version: number | undefined;
23
+ payload: Buffer | string | Promise<Buffer | string> | undefined;
24
+ failed: boolean;
25
+ hits: number;
26
+ bytes: number;
27
+ epoch: number;
28
+ frames: Map<number, Map<string, Buffer>> | undefined;
29
+ next: SharedMessageEncoding | undefined;
30
+ }
31
+
32
+ // A message that carries its own content type is passed through verbatim and never negotiated, so
33
+ // every subscriber shares one entry no matter what it negotiated. This sentinel stands in for the
34
+ // serializer that was deliberately not consulted.
35
+ const PASS_THROUGH = function passThrough() {};
36
+
37
+ // THE IDENTITY CONTRACT. A fan-out has a single shared origin: the same message object instance is
38
+ // dispatched to every subscription of a key (resources/transactionBroadcast.ts), so identity is
39
+ // what lets the first subscriber to encode do the work for all of them. This is only sound because
40
+ // every internal producer yields a *fresh object per version* — transactionBroadcast hands one
41
+ // auditRecord to every subscription, auditStore's getValue memoizes the decode in its closure, and
42
+ // primaryStore.getEntry is guarded by a version check — so identity implies equal content, and a
43
+ // miss (a primitive message, or a store cache eviction between subscribers) only costs the
44
+ // redundant encode we have today rather than yielding stale bytes.
45
+ //
46
+ // A custom Resource is not bound by that, so identity alone is not trusted: the event's record
47
+ // version is part of the key (see getSharedMessageEncoding), which makes reusing one envelope
48
+ // across publishes correct as long as the version advances, and refuses to share at all when there
49
+ // is no version to tell one publish from the next.
50
+ //
51
+ // Retention is bounded by rotating generations rather than by the message object's lifetime: for
52
+ // record events the message IS the store's cached record, so hanging encodings off it alone would
53
+ // keep serialized copies and whole PUBLISH buffers resident for as long as the record stays cached,
54
+ // while sharing is only ever needed for the duration of one fan-out. Two generations are kept so a
55
+ // fan-out spanning a rotation still hits; dropping a generation releases all of it at once.
56
+ const ROTATE_INTERVAL_MS = 10_000;
57
+ // Time alone bounds how LONG an entry is retained, not how MUCH: at high throughput on
58
+ // single-subscriber topics the interval's worth of payloads would all be live at once, for no
59
+ // benefit. The byte budget puts a ceiling on that, at the cost of a fan-out that spans an early
60
+ // rotation falling back to re-encoding — slower, never wrong. Note this is the ceiling for ONE
61
+ // generation; the previous generation can hold as much again, so steady-state retention is up to
62
+ // twice this per worker thread.
63
+ export const MAX_RETAINED_BYTES = 4_000_000;
64
+ let currentGeneration = new WeakMap<object, SharedMessageEncoding>();
65
+ let previousGeneration = new WeakMap<object, SharedMessageEncoding>();
66
+ // Rotation runs on a timer, not on a delivery counter: the bound has to hold when traffic stops,
67
+ // which is exactly when a delivery-gated check would never fire again. Insert counts only decide
68
+ // when the timer can stop — a WeakMap can not be asked whether it is empty.
69
+ let rotationTimer: ReturnType<typeof setInterval> | undefined;
70
+ let currentInserts = 0;
71
+ let currentBytes = 0;
72
+ // Identifies the generation an entry's bytes are charged to. Work can land after a rotation — a
73
+ // serialization that resolves late, a frame generated by a subscriber that arrived slowly — and
74
+ // charging that to the current budget would bill a generation the bytes do not belong to, then bill
75
+ // them again when a promotion re-charges the entry.
76
+ const UNRETAINED = -1;
77
+ // starts at 1 so UNRETAINED can never collide with `currentEpoch - 1`, which would make charge()
78
+ // treat a never-retained entry as one still live in the previous generation
79
+ let currentEpoch = 1;
80
+
81
+ /** Retire the older generation. Exported for the rotation timer and for tests. */
82
+ export function rotateSharedEncodings() {
83
+ previousGeneration = currentGeneration;
84
+ currentGeneration = new WeakMap();
85
+ currentEpoch++;
86
+ const rotatedInserts = currentInserts;
87
+ currentInserts = 0;
88
+ currentBytes = 0;
89
+ if (rotatedInserts === 0 && rotationTimer !== undefined) {
90
+ // nothing is retained in either generation, so stop ticking until the next insert
91
+ clearInterval(rotationTimer);
92
+ rotationTimer = undefined;
93
+ }
94
+ }
95
+
96
+ /** Whether the rotation timer is currently armed. Introspection for tests. */
97
+ export function isRotationScheduled(): boolean {
98
+ return rotationTimer !== undefined;
99
+ }
100
+
101
+ /** Bytes charged to the live generation. Introspection so tests can pin the accounting exactly. */
102
+ export function getRetainedBytes(): number {
103
+ return currentBytes;
104
+ }
105
+
106
+ function retainedSize(payload: SharedMessageEncoding['payload']): number {
107
+ // a pending promise is accounted for when it resolves
108
+ if (typeof payload === 'string') return Buffer.byteLength(payload);
109
+ return (payload as Buffer)?.byteLength ?? 0;
110
+ }
111
+
112
+ /** Add to an entry's footprint, and to the budget if the entry is live. */
113
+ function charge(encoding: SharedMessageEncoding, bytes: number) {
114
+ encoding.bytes += bytes;
115
+ if (encoding.epoch === currentEpoch) currentBytes += bytes;
116
+ else if (encoding.epoch === currentEpoch - 1) {
117
+ // Bytes can land after a rotation — a serialization resolving late, or a frame generated by a
118
+ // subscriber whose await spanned one. The entry is still live in the previous generation, so
119
+ // fold its whole footprint into the live budget; charging only the new bytes would leave the
120
+ // rest counted by no generation at all, and charging nothing would under-report the ceiling.
121
+ encoding.epoch = currentEpoch;
122
+ currentBytes += encoding.bytes;
123
+ }
124
+ }
125
+
126
+ /** Give back everything a chain holds, for an entry that is being discarded rather than refilled. */
127
+ function release(encoding: SharedMessageEncoding) {
128
+ for (let node = encoding; node !== undefined; node = node.next) {
129
+ if (node.epoch === currentEpoch) currentBytes -= node.bytes;
130
+ node.epoch = UNRETAINED;
131
+ }
132
+ }
133
+
134
+ function retain(message: object, encoding: SharedMessageEncoding) {
135
+ if (currentBytes >= MAX_RETAINED_BYTES) rotateSharedEncodings();
136
+ currentGeneration.set(message, encoding);
137
+ currentInserts++;
138
+ // charges the whole chain: on a promotion this re-charges everything the entry holds, since
139
+ // rotation zeroed the counter but the bytes are still live
140
+ for (let node = encoding; node !== undefined; node = node.next) {
141
+ if (node.epoch !== currentEpoch) {
142
+ node.epoch = currentEpoch;
143
+ currentBytes += node.bytes;
144
+ }
145
+ }
146
+ if (rotationTimer === undefined) {
147
+ rotationTimer = setInterval(rotateSharedEncodings, ROTATE_INTERVAL_MS);
148
+ rotationTimer.unref?.();
149
+ }
150
+ }
151
+
152
+ function fill(encoding: SharedMessageEncoding, message: any, request: any) {
153
+ // whatever this entry was holding is being replaced, so give the bytes back before re-charging
154
+ if (encoding.epoch === currentEpoch) currentBytes -= encoding.bytes;
155
+ encoding.bytes = 0;
156
+ encoding.frames = undefined;
157
+ // Pessimistic: an entry is only valid once a payload is actually in hand. Set optimistically,
158
+ // a synchronous throw here would leave an already-retained entry claiming success with no
159
+ // payload, and every later subscriber would send an empty PUBLISH instead of erroring.
160
+ encoding.failed = true;
161
+ encoding.payload = undefined;
162
+ const payload = serializeMessage(message, request);
163
+ encoding.payload = payload;
164
+ encoding.failed = false;
165
+ // A pass-through payload IS the message's own data, already reachable from the WeakMap key, so
166
+ // caching it retains nothing extra and must not be billed against the budget.
167
+ if (encoding.serializer === PASS_THROUGH) return;
168
+ if (typeof (payload as any)?.then === 'function')
169
+ // collapse an async serialization in place so later subscribers, and frame sharing, see the
170
+ // finished buffer rather than re-entering the async path
171
+ encoding.payload = (payload as Promise<Buffer | string>).then(
172
+ (resolved) => {
173
+ charge(encoding, retainedSize(resolved));
174
+ return (encoding.payload = resolved);
175
+ },
176
+ (error) => {
177
+ // mark for retry rather than memoize the failure: a shared rejected promise would turn
178
+ // one transient serialization error into a permanent one for every later subscriber
179
+ encoding.failed = true;
180
+ encoding.payload = undefined;
181
+ throw error;
182
+ }
183
+ );
184
+ else charge(encoding, retainedSize(payload));
185
+ }
186
+
187
+ function encode(message: any, request: any, serializer: Function, version?: number): SharedMessageEncoding {
188
+ const encoding: SharedMessageEncoding = {
189
+ serializer,
190
+ version,
191
+ payload: undefined,
192
+ failed: false,
193
+ hits: 0,
194
+ bytes: 0,
195
+ epoch: UNRETAINED,
196
+ frames: undefined,
197
+ next: undefined,
198
+ };
199
+ fill(encoding, message, request);
200
+ return encoding;
201
+ }
202
+
203
+ function reuse(encoding: SharedMessageEncoding, message: any, request: any): SharedMessageEncoding {
204
+ encoding.hits++;
205
+ if (encoding.failed) fill(encoding, message, request);
206
+ return encoding;
207
+ }
208
+
209
+ /**
210
+ * Get the encoding shared by every subscriber that negotiated the same content type. Keyed on the
211
+ * message object's identity, the serializer function (which is what `serializeMessage` output
212
+ * varies on), and the event's record `version`.
213
+ *
214
+ * The version is part of the key, not a permission to share. Identity alone would be unsafe for a
215
+ * producer that reuses one mutable envelope across publishes — an app Resource wrapping a table
216
+ * subscription to enrich events can easily do that, and copies the version straight through with a
217
+ * spread — so a cached entry whose version does not match is treated as a miss and re-encoded.
218
+ * That leaves only same-object-and-same-version mutation, which is indistinguishable from "the same
219
+ * message". An event with no version at all is not shared: nothing then distinguishes one publish
220
+ * from the next.
221
+ */
222
+ export function getSharedMessageEncoding(message: any, request?: any, version?: number): SharedMessageEncoding {
223
+ // Negotiation must not run for a pass-through message: an Accept header naming only unsupported
224
+ // types throws 406, which would kill a delivery that used to succeed by returning message.data.
225
+ const serializer =
226
+ message?.contentType != null && message.data != null ? PASS_THROUGH : getMessageSerializer(request);
227
+ // primitives can not key a WeakMap, and are cheap to encode anyway; these stay per-subscriber
228
+ if (message === null || typeof message !== 'object' || typeof version !== 'number')
229
+ return encode(message, request, serializer);
230
+ let encoding = currentGeneration.get(message);
231
+ if (encoding === undefined) {
232
+ encoding = previousGeneration.get(message);
233
+ // promote a surviving entry so it lives through the next rotation
234
+ if (encoding !== undefined && encoding.version === version) retain(message, encoding);
235
+ }
236
+ if (encoding !== undefined && encoding.version !== version) {
237
+ // the same object carrying a new version: every content type on the chain is stale, so give
238
+ // back what the whole chain held and start over rather than serving the earlier message
239
+ release(encoding);
240
+ encoding = undefined;
241
+ }
242
+ if (encoding === undefined) {
243
+ retain(message, (encoding = encode(message, request, serializer, version)));
244
+ return encoding;
245
+ }
246
+ let last: SharedMessageEncoding;
247
+ do {
248
+ if (encoding.serializer === serializer) return reuse(encoding, message, request);
249
+ last = encoding;
250
+ encoding = encoding.next;
251
+ } while (encoding !== undefined);
252
+ // a second content type on an already-retained message is retained with it, so it is charged too
253
+ const chained = encode(message, request, serializer, version);
254
+ chained.epoch = last.epoch;
255
+ if (chained.epoch === currentEpoch) currentBytes += chained.bytes;
256
+ return (last.next = chained);
257
+ }
258
+
259
+ /**
260
+ * Resolve a still-pending shared serialization, retrying once through a fresh lookup if it failed.
261
+ * Every subscriber currently in the fan-out awaits the same promise, so without this one transient
262
+ * failure would disconnect all of them, where before the encoding was shared each subscriber
263
+ * serialized — and so retried — on its own.
264
+ */
265
+ export async function resolveSharedPayload(
266
+ encoding: SharedMessageEncoding,
267
+ message: any,
268
+ request: any,
269
+ version?: number
270
+ ): Promise<Buffer | string> {
271
+ try {
272
+ return await (encoding.payload as Promise<Buffer | string>);
273
+ } catch (error) {
274
+ // otherwise a failure that the retry recovers from leaves no trace at all
275
+ logger.debug?.('Shared message serialization failed, retrying for this subscriber', error);
276
+ // The entry is marked for retry, or a peer in this same wave has already refilled it — either
277
+ // way, ask again. The first subscriber here re-encodes and the rest share that attempt; if it
278
+ // fails too, that rejection propagates and the caller handles it as it did before sharing.
279
+ return await getSharedMessageEncoding(message, request, version).payload;
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Look up a fully encoded frame shared across subscribers, or undefined if it has not been
285
+ * generated yet. Split from `setSharedFrame` so a cache hit — the whole point on a fan-out —
286
+ * allocates nothing, not even a generator closure.
287
+ */
288
+ export function getSharedFrame(encoding: SharedMessageEncoding, version: number, topic: string): Buffer | undefined {
289
+ return encoding.frames?.get(version)?.get(topic);
290
+ }
291
+
292
+ /**
293
+ * Store a generated frame for reuse by the remaining subscribers, and return it. Call only when
294
+ * `encoding.hits > 0`: a frame stored for a fan-out of one is never read, and would keep a whole
295
+ * PUBLISH buffer reachable from the message object for the rest of its retention window.
296
+ */
297
+ export function setSharedFrame(encoding: SharedMessageEncoding, version: number, topic: string, frame: Buffer): Buffer {
298
+ let frames = encoding.frames;
299
+ if (frames === undefined) encoding.frames = frames = new Map();
300
+ let byTopic = frames.get(version);
301
+ if (byTopic === undefined) frames.set(version, (byTopic = new Map()));
302
+ // concurrent subscribers can each generate before any of them stores; only the retained buffer
303
+ // is charged, or the budget would bill every duplicate that is immediately garbage
304
+ if (!byTopic.has(topic)) charge(encoding, frame.byteLength);
305
+ byTopic.set(topic, frame);
306
+ return frame;
307
+ }
@@ -225,8 +225,23 @@ export async function createUwsServer(options: UwsServerOptions): Promise<{ app:
225
225
  app.any('/*', withBody);
226
226
 
227
227
  await new Promise<void>((resolve, reject) => {
228
- const onListen = (listenSocket: unknown) =>
229
- listenSocket ? resolve() : reject(new Error(`uWS failed to bind ${host ?? ''}:${port ?? socketPath}`));
228
+ let settled = false;
229
+ // Backstop against the native listen callback never firing at all — without it, a stuck
230
+ // bind is indistinguishable from a slow one, and nothing here ever rejects.
231
+ const bindTimeout = setTimeout(() => {
232
+ if (settled) return;
233
+ settled = true;
234
+ reject(
235
+ new Error(`uWS timed out waiting to bind ${host ?? ''}:${port ?? socketPath} (listen callback never fired)`)
236
+ );
237
+ }, 30_000);
238
+ const onListen = (listenSocket: unknown) => {
239
+ if (settled) return;
240
+ settled = true;
241
+ clearTimeout(bindTimeout);
242
+ if (listenSocket) resolve();
243
+ else reject(new Error(`uWS failed to bind ${host ?? ''}:${port ?? socketPath}`));
244
+ };
230
245
  // uWS shares the port across workers (SO_REUSEPORT) by default, matching the Node reusePort path.
231
246
  if (port != null) {
232
247
  if (host) app.listen(host, port, onListen);
package/server/static.ts CHANGED
@@ -5,6 +5,7 @@ import { resolveBaseURLPath } from '../components/resolveBaseURLPath.ts';
5
5
  import { convertToMS } from '../utility/common_utils.ts';
6
6
  import { isMatch } from 'micromatch';
7
7
  import send from 'send';
8
+ import { settleDeferredCredentialRejection } from '../security/deferredAuthentication.ts';
8
9
 
9
10
  /**
10
11
  * The static plugin handles serving static files from the respective application directory.
@@ -337,40 +338,30 @@ export function handleApplication(scope: Scope) {
337
338
  // Retrieve index entry
338
339
  staticFile = indexEntries.get(req.pathname);
339
340
 
340
- // The router strips both '/assets' and '/assets/' down to '/', so the mount root
341
- // must be disambiguated via the unstripped pathname (exposed by stripPrefix):
342
- // redirect the no-slash form so relative links on the index page resolve under
343
- // the mount (#1583). Query string is preserved across both redirects; compute it
344
- // lazily inside each branch so the common (non-redirect) index serve stays allocation-free.
345
- // Gated on the EXTERNAL base path, not the plugin-local one: a root-level static
346
- // plugin (baseURLPath === '/') still needs this redirect when the application
347
- // itself carries a host/urlPath mount, since the client-visible mount root is then
348
- // externalBaseURLPath, not '/' (review finding).
349
- if (staticFile && req.pathname === '/' && externalBaseURLPath !== '/') {
350
- const originalPathname: string | undefined = (req as any).originalPathname;
351
- if (originalPathname && !originalPathname.endsWith('/')) {
352
- const queryIndex = (req.url as string).indexOf('?');
353
- const query = queryIndex === -1 ? '' : (req.url as string).slice(queryIndex);
354
- return {
355
- status: 301,
356
- headers: {
357
- Location: externalBaseURLPath + query,
358
- },
359
- };
360
- }
361
- }
341
+ // Prefix stripping makes `originalPathname` necessary to distinguish mounted roots (#1583).
342
+ const originalPathname: string | undefined = (req as any).originalPathname;
343
+ const redirectsMountRoot = !!(
344
+ staticFile &&
345
+ req.pathname === '/' &&
346
+ externalBaseURLPath !== '/' &&
347
+ originalPathname &&
348
+ !originalPathname.endsWith('/')
349
+ );
362
350
 
363
- // If `null`, redirect to trailing slash. req.pathname arrives with the mount
364
- // prefix stripped, so rebuild the external path for the Location header (#1583)
365
- if (staticFile === null) {
366
- const externalPath =
367
- externalBaseURLPath === '/' ? req.pathname : externalBaseURLPath.slice(0, -1) + req.pathname;
351
+ if (redirectsMountRoot || staticFile === null) {
352
+ const settledCredentialRejection = settleDeferredCredentialRejection(req);
353
+ if (settledCredentialRejection) return settledCredentialRejection;
368
354
  const queryIndex = (req.url as string).indexOf('?');
369
355
  const query = queryIndex === -1 ? '' : (req.url as string).slice(queryIndex);
356
+ const location = redirectsMountRoot
357
+ ? externalBaseURLPath + query
358
+ : (externalBaseURLPath === '/' ? req.pathname : externalBaseURLPath.slice(0, -1) + req.pathname) +
359
+ '/' +
360
+ query;
370
361
  return {
371
362
  status: 301,
372
363
  headers: {
373
- Location: externalPath + '/' + query,
364
+ Location: location,
374
365
  },
375
366
  };
376
367
  }
@@ -393,6 +384,8 @@ export function handleApplication(scope: Scope) {
393
384
 
394
385
  // If an entry matched, serve it
395
386
  if (staticFile) {
387
+ const settledCredentialRejection = settleDeferredCredentialRejection(req);
388
+ if (settledCredentialRejection) return settledCredentialRejection;
396
389
  // The benefit to using `send` is that it handles a lot of edge cases and headers for us.
397
390
  return {
398
391
  handlesHeaders: true,
@@ -405,7 +398,8 @@ export function handleApplication(scope: Scope) {
405
398
  return next(req);
406
399
  }
407
400
 
408
- // Otherwise, handle not found
401
+ const settledCredentialRejection = settleDeferredCredentialRejection(req);
402
+ if (settledCredentialRejection) return settledCredentialRejection;
409
403
 
410
404
  const notFound = scope.options.get(['notFound']);
411
405