@harperfast/harper 5.2.10 → 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 (554) 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 -3
  150. package/dist/resources/DatabaseTransaction.js +460 -134
  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 +30 -2
  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 -10
  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 +1071 -197
  174. package/dist/resources/Table.js.map +1 -1
  175. package/dist/resources/auditStore.d.ts +11 -2
  176. package/dist/resources/auditStore.js +183 -18
  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 -9
  187. package/dist/resources/databases.js +1247 -525
  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 -32
  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 +5 -0
  341. package/dist/server/storageReclamation.js +16 -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 -4
  347. package/dist/server/threads/manageThreads.js +517 -72
  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 +235 -233
  423. package/package.json +8 -7
  424. package/resources/DESIGN.md +114 -52
  425. package/resources/DatabaseTransaction.ts +522 -130
  426. package/resources/LMDBTransaction.ts +26 -4
  427. package/resources/PrimaryRocksDatabase.ts +29 -3
  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 -10
  433. package/resources/RocksTransactionLogStore.ts +78 -21
  434. package/resources/Table.ts +1107 -164
  435. package/resources/auditStore.ts +187 -21
  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 +1354 -522
  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 -32
  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 +13 -0
  498. package/server/threads/itc.js +11 -1
  499. package/server/threads/manageThreads.js +526 -63
  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-Br06zdMA.js → Chat-BnCBegQz.js} +1 -1
  505. package/studio/web/assets/{FloatingChat-BWImX5fA.js → FloatingChat-CoDW1ySS.js} +3 -3
  506. package/studio/web/assets/{apiToken-DN0nmDsq.js → apiToken-Bwk5BLXW.js} +1 -1
  507. package/studio/web/assets/{applications-kSxVoyeU.js → applications-DHxGi7JH.js} +1 -1
  508. package/studio/web/assets/{cssMode-C1JeufH5.js → cssMode-s0cWI-_M.js} +1 -1
  509. package/studio/web/assets/{editor-qoo9CrGO.js → editor-DNcRHK54.js} +1 -1
  510. package/studio/web/assets/{html-Dt4IIy04.js → html-Bdssedlg.js} +1 -1
  511. package/studio/web/assets/{htmlMode-DXgKKr4C.js → htmlMode-CoDlJ3fw.js} +1 -1
  512. package/studio/web/assets/{index-6onkYFOG.js → index-D6sxmFLR.js} +5 -5
  513. package/studio/web/assets/{index.lazy-BrCFnpNJ.js → index.lazy-tmU5BS8s.js} +1 -1
  514. package/studio/web/assets/{javascript-DNCQGUBc.js → javascript-B8meVSTH.js} +1 -1
  515. package/studio/web/assets/{jsonMode-CR6HWruP.js → jsonMode-DpIPd35T.js} +1 -1
  516. package/studio/web/assets/{languageServices-BM4fI4rS.js → languageServices-C_5FMJzQ.js} +1 -1
  517. package/studio/web/assets/{lspLanguageFeatures-DSa1ttcD.js → lspLanguageFeatures-BIzNBzPK.js} +1 -1
  518. package/studio/web/assets/{notifications-BHXLnh6x.js → notifications-CQf18QKb.js} +1 -1
  519. package/studio/web/assets/{notifications-CUmtIA6z.js → notifications-CvZivSbh.js} +1 -1
  520. package/studio/web/assets/{profile-8BeFSF3j.js → profile-DdOwtntb.js} +1 -1
  521. package/studio/web/assets/{regions-C8qR0HhD.js → regions-n69fwagr.js} +1 -1
  522. package/studio/web/assets/{register-B4n5i0SD.js → register-PfWTCXWB.js} +2 -2
  523. package/studio/web/assets/{setComponentFile-g0_B0lgX.js → setComponentFile-Bg6O7X0S.js} +1 -1
  524. package/studio/web/assets/{setup-B0CTj_Q5.js → setup-CUx_aUDl.js} +2 -2
  525. package/studio/web/assets/{status-C6Yib7-K.js → status-D7BVKqX9.js} +1 -1
  526. package/studio/web/assets/{toggleHighContrast-Dgta7bVi.js → toggleHighContrast-DBSyXzMr.js} +1 -1
  527. package/studio/web/assets/{tsMode-CH_jHvU-.js → tsMode-BByKCjBS.js} +1 -1
  528. package/studio/web/assets/{typescript-Co9LCXd5.js → typescript-DDLnLpw9.js} +1 -1
  529. package/studio/web/assets/{useEntityRestURL-wKC8NsC_.js → useEntityRestURL-31CHGaHk.js} +1 -1
  530. package/studio/web/assets/{workers-CWeLxCXA.js → workers-pR3jRY9D.js} +1 -1
  531. package/studio/web/assets/{xml-BadC-0Rk.js → xml-2iRnMhQO.js} +1 -1
  532. package/studio/web/assets/{yaml-BiUfxPbC.js → yaml-Bf92gJpd.js} +1 -1
  533. package/studio/web/index.html +1 -1
  534. package/upgrade/directives/5-3-0.ts +132 -0
  535. package/upgrade/directives/directivesController.ts +2 -1
  536. package/utility/OperationFunctionCaller.ts +2 -1
  537. package/utility/common_utils.ts +30 -5
  538. package/utility/componentNames.ts +12 -0
  539. package/utility/environment/environmentManager.ts +3 -7
  540. package/utility/environment/systemInformation.ts +7 -0
  541. package/utility/errors/commonErrors.ts +4 -0
  542. package/utility/errors/hdbError.ts +29 -0
  543. package/utility/hdbTerms.ts +17 -0
  544. package/utility/logging/harper_logger.ts +87 -14
  545. package/utility/logging/logRotator.ts +72 -45
  546. package/utility/nodeIdentity.ts +45 -0
  547. package/utility/npmUtilities.ts +10 -8
  548. package/utility/operationPermissions.ts +18 -1
  549. package/utility/operation_authorization.ts +231 -42
  550. package/utility/watchPath.ts +63 -0
  551. package/utility/watcherFallback.ts +270 -0
  552. package/validation/configValidator.ts +209 -72
  553. package/validation/installValidator.ts +15 -0
  554. package/validation/validationWrapper.ts +18 -4
@@ -0,0 +1,71 @@
1
+ import { ClientError } from '../utility/errors/hdbError.ts';
2
+ import { serializeMessage, findBestSerializer } from '../server/serverHelpers/contentTypes.ts';
3
+ import { Headers } from '../server/serverHelpers/Headers.ts';
4
+
5
+ export { isCredentialRejection, markCredentialRejection, credentialRejectionError } from './credentialRejection.ts';
6
+
7
+ const DEFERRED_CREDENTIAL_REJECTION = Symbol('harper.deferredCredentialRejection');
8
+
9
+ export type DeferredCredentialRejection = {
10
+ readonly status: number;
11
+ readonly message: string;
12
+ readonly strategy: string;
13
+ };
14
+
15
+ const CREDENTIAL_REJECTION_STATUS = 401;
16
+
17
+ /**
18
+ * Records that this request presented a credential Harper rejected, without deciding the request.
19
+ * The caller leaves `request.user` unset and the inbound `Authorization` header untouched.
20
+ *
21
+ * The immutable, non-enumerable descriptor prevents downstream middleware from clearing it and
22
+ * keeps it out of request copies and serialization.
23
+ */
24
+ export function deferCredentialRejection(request: any, error: { message?: string }, strategy: string): void {
25
+ if (getDeferredCredentialRejection(request)) return;
26
+ const deferred: DeferredCredentialRejection = Object.freeze({
27
+ status: CREDENTIAL_REJECTION_STATUS,
28
+ message: error?.message ?? 'Unauthorized',
29
+ strategy,
30
+ });
31
+ Object.defineProperty(request, DEFERRED_CREDENTIAL_REJECTION, {
32
+ value: deferred,
33
+ enumerable: false,
34
+ configurable: false,
35
+ writable: false,
36
+ });
37
+ }
38
+
39
+ export function getDeferredCredentialRejection(request: any): DeferredCredentialRejection | undefined {
40
+ return request?.[DEFERRED_CREDENTIAL_REJECTION];
41
+ }
42
+
43
+ /**
44
+ * The response an owning layer returns once it has established Harper owns the route: exactly the
45
+ * descriptor `security/auth.ts` returns in-line, so immediate and deferred rejection share a wire
46
+ * contract.
47
+ *
48
+ * Owner-specific error mapping must not run first. REST renders a thrown error as an RFC 9457
49
+ * Problem Details document and GraphQL as `{errors:[…]}` rather than authentication's negotiated
50
+ * `{error: message}` response. `security/auth.ts` likewise leaves a settled rejection's status and
51
+ * challenge headers alone, so it stays byte-identical to the in-line 401 it replaced.
52
+ *
53
+ * Returns `undefined` when nothing was deferred, so a caller can `return settled ?? …` inline.
54
+ */
55
+ export function settleDeferredCredentialRejection(
56
+ request: any
57
+ ): { status: number; headers: Headers; body: string | Buffer } | undefined {
58
+ const deferred = getDeferredCredentialRejection(request);
59
+ if (!deferred) return undefined;
60
+ const contentType = (request?.headers ? findBestSerializer(request).type : undefined) ?? 'application/json';
61
+ return {
62
+ status: deferred.status,
63
+ headers: new Headers({ 'Content-Type': contentType }),
64
+ body: serializeMessage({ error: deferred.message }, request) as string | Buffer,
65
+ };
66
+ }
67
+
68
+ export function assertNoDeferredCredentialRejection(request: any): void {
69
+ const deferred = getDeferredCredentialRejection(request);
70
+ if (deferred) throw new ClientError(deferred.message, deferred.status);
71
+ }
@@ -1,10 +1,46 @@
1
- import type { User } from './user.ts';
1
+ import { createHash } from 'node:crypto';
2
+ import type { User, UserRole } from './user.ts';
2
3
  import type { ImpersonatePayload } from '../server/operationsServer.ts';
3
4
  import { getUsersWithRolesCache } from './user.ts';
4
5
  import { validateOperations } from '../utility/operationPermissions.ts';
6
+ import { addRoleValidation } from '../validation/role_validation.ts';
5
7
  import { ClientError } from '../utility/errors/hdbError.ts';
6
8
  import harperLogger from '../utility/logging/harper_logger.ts';
7
9
  import { getRoleByName } from './role.ts';
10
+ import { attachScopeToUser } from './operationScope.ts';
11
+ import { attachWorkloadIdentityToUser } from './credentialProvenance.ts';
12
+
13
+ /**
14
+ * Content-derived identity for synthetic (inline) roles. getRolePermissions memoizes translated
15
+ * permissions by role name, so synthetic roles must never share a constant name: two inline roles
16
+ * with different permissions would alias in that cache and leak permissions across principals.
17
+ * Hashing the (already downgraded) permission content isolates distinct permission sets while
18
+ * letting identical ones share a cache entry. The paired __updatedtime__ of 0 keeps the memo key
19
+ * stable across requests; the content hash in the name is what invalidates on permission change.
20
+ *
21
+ * Object keys are canonicalized before hashing so two structurally-identical permission sets that
22
+ * differ only in key order (e.g. from different client request shapes) map to the same name and
23
+ * share one cache slot — otherwise they would each consume a distinct slot (never an aliasing bug,
24
+ * but it worsens the bounded synthetic-role cache pressure).
25
+ */
26
+ export function syntheticRoleName(prefix: string, permission: object): string {
27
+ return `${prefix}_${createHash('sha256').update(canonicalJSON(permission)).digest('hex').slice(0, 24)}`;
28
+ }
29
+
30
+ // Array order is intentionally preserved: operations is order-insensitive semantically, but
31
+ // canonicalizing it too would be a broader behavior change than this cache-sharing fix needs.
32
+ function canonicalJSON(value: any): string {
33
+ return JSON.stringify(value, (_key, v) =>
34
+ v && typeof v === 'object' && !Array.isArray(v)
35
+ ? Object.keys(v)
36
+ .sort()
37
+ .reduce((acc: any, k) => {
38
+ acc[k] = v[k];
39
+ return acc;
40
+ }, {})
41
+ : v
42
+ );
43
+ }
8
44
 
9
45
  /**
10
46
  * Applies impersonation to a request. The authenticated user must be a super_user.
@@ -38,6 +74,26 @@ export async function applyImpersonation(authenticatedUser: User, payload: Imper
38
74
  // Enforce downgrade: never allow escalation
39
75
  enforceDowngrade(impersonatedUser);
40
76
 
77
+ // A token's operation scope (#2174) constrains the credential regardless of which principal it
78
+ // acts as, so it survives impersonation. enforceDowngrade only bounds the impersonated role's
79
+ // permissions; without carrying the scope, a scoped super_user token would shed it by impersonating.
80
+ attachScopeToUser(impersonatedUser, (authenticatedUser as any).tokenOperations);
81
+ // Same reasoning for provenance (#2171), and the omission would be worse: impersonation returns a
82
+ // NEW principal, so dropping the marker here would let a workload token impersonate — even down to
83
+ // a lesser role — and then mint a 30-day credential that createTokens would no longer refuse.
84
+ attachWorkloadIdentityToUser(impersonatedUser, (authenticatedUser as any).fromWorkloadIdentity);
85
+
86
+ // Re-key the synthetic role by its effective (post-downgrade) content so it can never alias
87
+ // another impersonation's permissions or poison a persisted role's memoized translation —
88
+ // getRolePermissions caches by role name (see syntheticRoleName).
89
+ if (impersonatedUser.role) {
90
+ impersonatedUser.role = {
91
+ ...impersonatedUser.role,
92
+ role: syntheticRoleName('_impersonated', impersonatedUser.role.permission),
93
+ __updatedtime__: 0,
94
+ };
95
+ }
96
+
41
97
  // Tag for audit trail
42
98
  impersonatedUser._impersonated = true;
43
99
  impersonatedUser._impersonatedBy = authenticatedUser.username;
@@ -49,9 +105,60 @@ export async function applyImpersonation(authenticatedUser: User, payload: Imper
49
105
  return impersonatedUser;
50
106
  }
51
107
 
52
- function validatePayload(payload: ImpersonatePayload): void {
108
+ /**
109
+ * Builds the synthetic user embedded in a scoped authentication token
110
+ * (create_authentication_tokens with an inline `role` object). Same gate and downgrade rules as
111
+ * impersonation Mode A. `trusted` marks internal dispatch (operation authorization bypassed),
112
+ * where no authenticated minter exists.
113
+ */
114
+ export async function buildScopedTokenUser(
115
+ minter: User | undefined,
116
+ payload: ImpersonatePayload,
117
+ trusted = false
118
+ ): Promise<User> {
119
+ if (!trusted && !minter?.role?.permission?.super_user) {
120
+ throw new ClientError('Only super_user can create a token with an inline role', 403);
121
+ }
122
+ validatePayload(payload, 'scoped token role');
123
+ if (!payload.role) {
124
+ throw new ClientError("A scoped token requires 'role' with 'permission'");
125
+ }
126
+ const username = payload.username || (minter?.username && `scoped:${minter.username}`);
127
+ if (!username || typeof username !== 'string') {
128
+ throw new ClientError("A scoped token requires a 'username'");
129
+ }
130
+ // The attribution name must never collide with a real principal: paths that rehydrate a user
131
+ // by name (e.g. MQTT last-will replay) would resolve the token's bearer to that user's full
132
+ // permissions. This also keeps scoped-token activity distinguishable in audit logs.
133
+ if ((await getUsersWithRolesCache())?.has(username)) {
134
+ throw new ClientError(`'username' must not name an existing user; scoped-token attribution is a label`);
135
+ }
136
+ // Downgrade first so validation and the content hash see the effective permission set.
137
+ const permission = {
138
+ ...payload.role.permission,
139
+ super_user: false,
140
+ cluster_user: false,
141
+ } as UserRole['permission'];
142
+ // Full persisted-role validation: a malformed shape must fail at mint (400), not at every use.
143
+ const deepValidation = addRoleValidation({ role: 'scoped_token', permission });
144
+ if (deepValidation) throw deepValidation;
145
+ const roleName = syntheticRoleName('_scoped_token', permission);
146
+ return {
147
+ username,
148
+ active: true,
149
+ role: {
150
+ permission,
151
+ role: roleName,
152
+ id: roleName,
153
+ __updatedtime__: 0,
154
+ __createdtime__: 0,
155
+ },
156
+ };
157
+ }
158
+
159
+ function validatePayload(payload: ImpersonatePayload, context = 'impersonate payload'): void {
53
160
  if (typeof payload !== 'object' || payload === null || Array.isArray(payload)) {
54
- throw new ClientError('Invalid impersonate payload: must be an object');
161
+ throw new ClientError(`Invalid ${context}: must be an object`);
55
162
  }
56
163
 
57
164
  const hasRole = payload.role !== undefined;
@@ -59,33 +166,31 @@ function validatePayload(payload: ImpersonatePayload): void {
59
166
  const hasRoleName = typeof payload.role_name === 'string' && payload.role_name.length > 0;
60
167
 
61
168
  if (!hasRole && !hasUsername && !hasRoleName) {
62
- throw new ClientError(
63
- "Invalid impersonate payload: must include 'username', 'role_name', or 'role' with 'permission'"
64
- );
169
+ throw new ClientError(`Invalid ${context}: must include 'username', 'role_name', or 'role' with 'permission'`);
65
170
  }
66
171
 
67
172
  if (hasRole) {
68
173
  if (typeof payload.role !== 'object' || payload.role === null) {
69
- throw new ClientError("Invalid impersonate payload: 'role' must be an object");
174
+ throw new ClientError(`Invalid ${context}: 'role' must be an object`);
70
175
  }
71
176
  if (typeof payload.role.permission !== 'object' || payload.role.permission === null) {
72
- throw new ClientError("Invalid impersonate payload: 'role.permission' must be an object");
177
+ throw new ClientError(`Invalid ${context}: 'role.permission' must be an object`);
73
178
  }
74
- validateOperationsField(payload.role.permission);
179
+ validateOperationsField(payload.role.permission, context);
75
180
  }
76
181
  }
77
182
 
78
- function validateOperationsField(permission: Record<string, unknown>): void {
183
+ function validateOperationsField(permission: Record<string, unknown>, context = 'impersonate payload'): void {
79
184
  const operations = permission.operations;
80
185
  if (operations === undefined) return;
81
186
 
82
187
  if (!Array.isArray(operations)) {
83
- throw new ClientError("Invalid impersonate payload: 'operations' must be an array");
188
+ throw new ClientError(`Invalid ${context}: 'operations' must be an array`);
84
189
  }
85
190
 
86
191
  const invalidOp = validateOperations(operations);
87
192
  if (invalidOp !== null) {
88
- throw new ClientError(`Invalid impersonate payload: unknown operation '${invalidOp}'`);
193
+ throw new ClientError(`Invalid ${context}: unknown operation '${invalidOp}'`);
89
194
  }
90
195
  }
91
196
 
@@ -1,9 +1,9 @@
1
1
  import { Resource } from '../resources/Resource.ts';
2
2
  import { contextStorage, transaction } from '../resources/transaction.ts';
3
3
  import { RequestTarget } from '../resources/RequestTarget.ts';
4
- import { tables, databases } from '../resources/databases.ts';
4
+ import { tables, databases, scopedTableFactory } from '../resources/databases.ts';
5
5
  import { models as harperModelsSingleton } from '../resources/models/Models.ts';
6
- import { defineTable, types } from '../resources/defineTable.ts';
6
+ import { defineTable, defineTableUsing, types } from '../resources/defineTable.ts';
7
7
  import { defineResource, t, schemaOf, projectTableFragment } from '../resources/defineResource.ts';
8
8
  import { readFile } from 'node:fs/promises';
9
9
  import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
@@ -15,10 +15,12 @@ import logger from '../utility/logging/harper_logger.ts';
15
15
  import { createRequire } from 'node:module';
16
16
  import * as env from '../utility/environment/environmentManager';
17
17
  import * as child_process from 'node:child_process';
18
- import { CONFIG_PARAMS } from '../utility/hdbTerms.ts';
18
+ import { CONFIG_PARAMS, DEFAULT_DATABASE_NAME } from '../utility/hdbTerms.ts';
19
+
19
20
  import { contentTypes } from '../server/serverHelpers/contentTypes.ts';
20
21
  import type {} from 'ses';
21
22
  import {
23
+ existsSync,
22
24
  mkdirSync,
23
25
  readFileSync,
24
26
  writeFileSync,
@@ -174,13 +176,13 @@ function walkExportsConditions(entry: unknown, conditions: readonly string[]): s
174
176
 
175
177
  /**
176
178
  * Resolve a bare package specifier to a file:// URL using the package's exports map
177
- * with ESM import conditions. Used as a fallback when createRequire().resolve() throws
178
- * ERR_PACKAGE_PATH_NOT_EXPORTED for pure-ESM packages (exports map with only "import"
179
- * conditions and no "require").
179
+ * with ESM import conditions. Used as a fallback when the runtime's CommonJS resolver
180
+ * cannot match a pure-ESM package (exports map with only "import" conditions).
180
181
  */
181
182
  function resolveESMPackageExports(
182
183
  specifier: string,
183
- fromDir: string
184
+ fromDir: string,
185
+ preferRequireConditions = false
184
186
  ): { resolvedUrl: string; packageJsonUrl: string; packageJsonSource: Buffer } | null {
185
187
  const isScoped = specifier.startsWith('@');
186
188
  const parts = specifier.split('/');
@@ -223,11 +225,23 @@ function resolveESMPackageExports(
223
225
 
224
226
  if (!entry) return null;
225
227
 
226
- const relative = walkExportsConditions(entry, ['import', 'node', 'default']);
228
+ const relative = preferRequireConditions
229
+ ? (walkExportsConditions(entry, ['bun', 'require', 'node', 'default']) ??
230
+ walkExportsConditions(entry, ['bun', 'import', 'node', 'default']))
231
+ : walkExportsConditions(entry, ['import', 'node', 'default']);
227
232
  if (!relative) return null;
228
233
 
234
+ let resolvedPath = join(pkgRoot, relative);
235
+ if (preferRequireConditions && !existsSync(resolvedPath)) {
236
+ // The runtime's preferred condition (Bun's `require`) named a target that isn't
237
+ // actually on disk -- fall back to the plain ESM `import` condition instead of
238
+ // failing resolution outright.
239
+ const importRelative = walkExportsConditions(entry, ['import', 'node', 'default']);
240
+ if (importRelative) resolvedPath = join(pkgRoot, importRelative);
241
+ }
242
+
229
243
  return {
230
- resolvedUrl: pathToFileURL(realpathSync(join(pkgRoot, relative))).toString(),
244
+ resolvedUrl: pathToFileURL(realpathSync(resolvedPath)).toString(),
231
245
  packageJsonUrl: pathToFileURL(realpathSync(packageJsonPath)).toString(),
232
246
  packageJsonSource,
233
247
  };
@@ -325,9 +339,10 @@ async function loadModuleWithVM(moduleUrl: string, scope: ApplicationScope, useC
325
339
  const referrerDir = resolveReferrer.startsWith('file:')
326
340
  ? dirname(fileURLToPath(resolveReferrer))
327
341
  : dirname(resolveReferrer);
328
- const esmResolved = resolveESMPackageExports(specifier, referrerDir);
342
+ const esmResolved = resolveESMPackageExports(specifier, referrerDir, (err as any)?.code === 'MODULE_NOT_FOUND');
329
343
  if (esmResolved) {
330
344
  scope.recordLoadedModule?.(esmResolved.packageJsonUrl, esmResolved.packageJsonSource);
345
+ scope.recordLoadedModule?.(esmResolved.resolvedUrl, readFileSync(new URL(esmResolved.resolvedUrl)));
331
346
  return esmResolved.resolvedUrl;
332
347
  }
333
348
  }
@@ -849,6 +864,52 @@ function getGlobalObject(scope: ApplicationScope, copyIntrinsics = false) {
849
864
  // `Resource`/`tables`/`databases`/`createBlob`/… below are the live, process-wide singletons (the
850
865
  // same values surfaced as the top-level package exports and bare globals), not per-compartment
851
866
  // copies — only `server`/`logger`/`resources`/`config` are scope-overridable.
867
+ /**
868
+ * The `databases`/`tables` a scope sees. An application that declared `branchedDatabases` gets a view
869
+ * in which those names resolve to its private graph and everything else falls through to the real
870
+ * map, live: `databases` gains entries at runtime (`ensureDB`), so a copy taken at load would
871
+ * silently stop showing databases created afterwards.
872
+ *
873
+ * An unbranched scope gets the process-wide singletons **by identity**, not a view: that is the
874
+ * overwhelmingly common case and it must stay indistinguishable from before, and it means only
875
+ * branched applications pay for the indirection. Proxying rather than copying also keeps
876
+ * `databases.system` — deliberately non-enumerable (`resources/databases.ts`) — reachable for free.
877
+ */
878
+ function scopedDatabaseBindings(scope: ApplicationScope): { databases: any; tables: any } {
879
+ const branches = scope.branches;
880
+ if (!branches?.size) return { databases, tables };
881
+ // Every branched name already exists on the target as a writable, configurable property (a branch
882
+ // is only ever taken of a database that exists), so overriding it here breaks no Proxy invariant.
883
+ const scoped = new Proxy(databases, {
884
+ get: (target, key, receiver) =>
885
+ typeof key === 'string' && branches.has(key) ? branches.get(key)!.tables : Reflect.get(target, key, receiver),
886
+ getOwnPropertyDescriptor(target, key) {
887
+ if (typeof key !== 'string' || !branches.has(key)) return Reflect.getOwnPropertyDescriptor(target, key);
888
+ return { value: branches.get(key)!.tables, writable: true, enumerable: true, configurable: true };
889
+ },
890
+ });
891
+ // `tables` is the flat alias for the default database, so it follows that database's branch.
892
+ return { databases: scoped, tables: branches.get(DEFAULT_DATABASE_NAME)?.tables ?? tables };
893
+ }
894
+
895
+ /**
896
+ * `defineTable` for a branched application registers through that application's table factory, so
897
+ * a branched name lands in its branch; an unbranched application gets `defineTable` itself.
898
+ */
899
+ function scopedDefineTable(scope: ApplicationScope): typeof defineTable {
900
+ const branches = scope.branches;
901
+ if (!branches?.size) return defineTable;
902
+ const declareTable = scopedTableFactory(branches);
903
+ return function (name: string, shape: any, options?: any) {
904
+ return defineTableUsing(declareTable, name, shape, options);
905
+ } as typeof defineTable;
906
+ }
907
+
908
+ /** Everything an application sees differently because of what it declared. Built once, at load. */
909
+ export function scopedBindings(scope: ApplicationScope): { databases: any; tables: any; defineTable: any } {
910
+ return { ...scopedDatabaseBindings(scope), defineTable: scopedDefineTable(scope) };
911
+ }
912
+
852
913
  function getHarperExports(scope: ApplicationScope) {
853
914
  return {
854
915
  server: scope.server ?? server,
@@ -859,9 +920,7 @@ function getHarperExports(scope: ApplicationScope) {
859
920
  // the process-wide singletons below.
860
921
  secrets: getSecretsForComponent(scope.name),
861
922
  Resource,
862
- tables,
863
- databases,
864
- defineTable,
923
+ ...scopedBindings(scope),
865
924
  types,
866
925
  defineResource,
867
926
  t,
@@ -914,7 +973,6 @@ const ALLOWED_NODE_BUILTIN_MODULES = env.get(CONFIG_PARAMS.APPLICATIONS_ALLOWEDB
914
973
  return true;
915
974
  },
916
975
  };
917
- const ALLOWED_COMMANDS = new Set(env.get(CONFIG_PARAMS.APPLICATIONS_ALLOWEDSPAWNCOMMANDS) ?? []);
918
976
  const child_processConstrained: any = {
919
977
  exec: createSpawn(child_process.exec),
920
978
  execFile: createSpawn(child_process.execFile),
@@ -1070,10 +1128,15 @@ function acquirePidFileLock(
1070
1128
  }
1071
1129
 
1072
1130
  function createSpawn(spawnFunction: (...args: any) => child_process.ChildProcess, alwaysAllow?: boolean) {
1073
- const basePath = env.getHdbBasePath();
1074
1131
  return function (command: string, args?: any, options?: any, callback?: (...args: any[]) => void) {
1075
- if (!ALLOWED_COMMANDS.has(command.split(' ')[0]) && !alwaysAllow) {
1076
- throw new Error(`Command ${command} is not allowed`);
1132
+ // componentLoader imports this module, so it can load before the config is resolved; a value
1133
+ // captured out here would pin an empty allowlist, and an undefined base path, for the life of
1134
+ // the process. Anything but a configured list denies.
1135
+ if (!alwaysAllow) {
1136
+ const allowedCommands = env.get(CONFIG_PARAMS.APPLICATIONS_ALLOWEDSPAWNCOMMANDS);
1137
+ if (!Array.isArray(allowedCommands) || !allowedCommands.includes(command.split(' ')[0])) {
1138
+ throw new Error(`Command ${command} is not allowed`);
1139
+ }
1077
1140
  }
1078
1141
  const processName = options?.name;
1079
1142
  if (!processName)
@@ -1083,7 +1146,7 @@ function createSpawn(spawnFunction: (...args: any) => child_process.ChildProcess
1083
1146
  const requestedVersion = options?.version;
1084
1147
 
1085
1148
  // Ensure PID directory exists
1086
- const pidDir = join(basePath, 'pids');
1149
+ const pidDir = join(env.getHdbBasePath(), 'pids');
1087
1150
  mkdirSync(pidDir, { recursive: true });
1088
1151
 
1089
1152
  const pidFilePath = join(pidDir, `${processName}.pid`);