@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.
- package/agent/mcpTools.ts +1 -1
- package/agent/session.ts +25 -14
- package/bin/cliOperations.ts +46 -9
- package/bin/copyDb.ts +282 -59
- package/bin/deploySetup.ts +16 -5
- package/bin/harper.ts +1 -1
- package/bin/help.ts +4 -1
- package/bin/lite.ts +4 -1
- package/bin/restart.ts +59 -3
- package/bin/run.ts +6 -11
- package/bin/upgrade.js +7 -3
- package/bin/workloadIdentity.ts +119 -0
- package/components/Application.ts +2414 -242
- package/components/ApplicationScope.ts +8 -0
- package/components/EntryHandler.ts +59 -39
- package/components/OptionsWatcher.ts +150 -74
- package/components/RuntimeModuleTracker.ts +38 -7
- package/components/Scope.ts +37 -15
- package/components/awaitRestart.ts +84 -0
- package/components/componentLoader.ts +340 -30
- package/components/componentPreparationLock.ts +16 -5
- package/components/mcp/adapters/harperHttp.ts +4 -0
- package/components/mcp/listChanged.ts +4 -0
- package/components/mcp/toolRegistry.ts +2 -0
- package/components/mcp/tools/operations.ts +9 -0
- package/components/mcp/tools/schemas/operationDescriptions.ts +2 -2
- package/components/operations.js +270 -78
- package/components/operationsValidation.js +49 -1
- package/components/status/ComponentStatusRegistry.ts +59 -0
- package/config/RootConfigWatcher.ts +80 -34
- package/config/configUtils.ts +291 -34
- package/config/harperConfigEnvVars.ts +170 -27
- package/config-root.schema.json +29 -0
- package/dataLayer/blobBackup.ts +160 -50
- package/dataLayer/delete.ts +6 -1
- package/dataLayer/harperBridge/ResourceBridge.ts +52 -8
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
- package/dataLayer/hdbInfoController.ts +34 -1
- package/dataLayer/insert.ts +44 -1
- package/dataLayer/rocksdbBackup.ts +53 -10
- package/dataLayer/schema.ts +11 -1
- package/dataLayer/schemaDescribe.ts +8 -1
- package/dist/agent/mcpTools.js +1 -1
- package/dist/agent/mcpTools.js.map +1 -1
- package/dist/agent/session.d.ts +22 -0
- package/dist/agent/session.js +26 -15
- package/dist/agent/session.js.map +1 -1
- package/dist/bin/cliOperations.js +48 -9
- package/dist/bin/cliOperations.js.map +1 -1
- package/dist/bin/copyDb.d.ts +12 -1
- package/dist/bin/copyDb.js +248 -60
- package/dist/bin/copyDb.js.map +1 -1
- package/dist/bin/deploySetup.d.ts +2 -0
- package/dist/bin/deploySetup.js +11 -3
- package/dist/bin/deploySetup.js.map +1 -1
- package/dist/bin/harper.js +1 -1
- package/dist/bin/harper.js.map +1 -1
- package/dist/bin/help.js +4 -1
- package/dist/bin/help.js.map +1 -1
- package/dist/bin/lite.js +4 -1
- package/dist/bin/lite.js.map +1 -1
- package/dist/bin/restart.js +54 -5
- package/dist/bin/restart.js.map +1 -1
- package/dist/bin/run.js +4 -10
- package/dist/bin/run.js.map +1 -1
- package/dist/bin/upgrade.js +4 -3
- package/dist/bin/upgrade.js.map +1 -1
- package/dist/bin/workloadIdentity.d.ts +18 -0
- package/dist/bin/workloadIdentity.js +100 -0
- package/dist/bin/workloadIdentity.js.map +1 -0
- package/dist/components/Application.d.ts +139 -16
- package/dist/components/Application.js +2215 -267
- package/dist/components/Application.js.map +1 -1
- package/dist/components/ApplicationScope.d.ts +8 -0
- package/dist/components/ApplicationScope.js +7 -0
- package/dist/components/ApplicationScope.js.map +1 -1
- package/dist/components/EntryHandler.js +26 -10
- package/dist/components/EntryHandler.js.map +1 -1
- package/dist/components/OptionsWatcher.d.ts +1 -0
- package/dist/components/OptionsWatcher.js +141 -74
- package/dist/components/OptionsWatcher.js.map +1 -1
- package/dist/components/RuntimeModuleTracker.js +40 -6
- package/dist/components/RuntimeModuleTracker.js.map +1 -1
- package/dist/components/Scope.js +38 -13
- package/dist/components/Scope.js.map +1 -1
- package/dist/components/awaitRestart.d.ts +33 -0
- package/dist/components/awaitRestart.js +61 -0
- package/dist/components/awaitRestart.js.map +1 -0
- package/dist/components/componentLoader.d.ts +38 -1
- package/dist/components/componentLoader.js +279 -22
- package/dist/components/componentLoader.js.map +1 -1
- package/dist/components/componentPreparationLock.d.ts +5 -0
- package/dist/components/componentPreparationLock.js +14 -6
- package/dist/components/componentPreparationLock.js.map +1 -1
- package/dist/components/mcp/adapters/harperHttp.js +4 -0
- package/dist/components/mcp/adapters/harperHttp.js.map +1 -1
- package/dist/components/mcp/listChanged.js +5 -0
- package/dist/components/mcp/listChanged.js.map +1 -1
- package/dist/components/mcp/toolRegistry.d.ts +1 -0
- package/dist/components/mcp/toolRegistry.js.map +1 -1
- package/dist/components/mcp/tools/operations.d.ts +5 -0
- package/dist/components/mcp/tools/operations.js +9 -0
- package/dist/components/mcp/tools/operations.js.map +1 -1
- package/dist/components/mcp/tools/schemas/operationDescriptions.js +2 -2
- package/dist/components/mcp/tools/schemas/operationDescriptions.js.map +1 -1
- package/dist/components/operations.js +231 -77
- package/dist/components/operations.js.map +1 -1
- package/dist/components/operationsValidation.js +49 -1
- package/dist/components/operationsValidation.js.map +1 -1
- package/dist/components/status/ComponentStatusRegistry.d.ts +0 -4
- package/dist/components/status/ComponentStatusRegistry.js +63 -0
- package/dist/components/status/ComponentStatusRegistry.js.map +1 -1
- package/dist/config/RootConfigWatcher.d.ts +7 -1
- package/dist/config/RootConfigWatcher.js +64 -27
- package/dist/config/RootConfigWatcher.js.map +1 -1
- package/dist/config/configUtils.d.ts +9 -1
- package/dist/config/configUtils.js +254 -33
- package/dist/config/configUtils.js.map +1 -1
- package/dist/config/harperConfigEnvVars.d.ts +16 -0
- package/dist/config/harperConfigEnvVars.js +162 -25
- package/dist/config/harperConfigEnvVars.js.map +1 -1
- package/dist/dataLayer/blobBackup.d.ts +49 -20
- package/dist/dataLayer/blobBackup.js +139 -50
- package/dist/dataLayer/blobBackup.js.map +1 -1
- package/dist/dataLayer/delete.js +1 -1
- package/dist/dataLayer/delete.js.map +1 -1
- package/dist/dataLayer/harperBridge/ResourceBridge.d.ts +14 -1
- package/dist/dataLayer/harperBridge/ResourceBridge.js +51 -10
- package/dist/dataLayer/harperBridge/ResourceBridge.js.map +1 -1
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.d.ts +3 -1
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js.map +1 -1
- package/dist/dataLayer/hdbInfoController.d.ts +10 -0
- package/dist/dataLayer/hdbInfoController.js +30 -1
- package/dist/dataLayer/hdbInfoController.js.map +1 -1
- package/dist/dataLayer/insert.d.ts +9 -1
- package/dist/dataLayer/insert.js +30 -0
- package/dist/dataLayer/insert.js.map +1 -1
- package/dist/dataLayer/rocksdbBackup.d.ts +2 -2
- package/dist/dataLayer/rocksdbBackup.js +45 -8
- package/dist/dataLayer/rocksdbBackup.js.map +1 -1
- package/dist/dataLayer/schema.js +8 -0
- package/dist/dataLayer/schema.js.map +1 -1
- package/dist/dataLayer/schemaDescribe.js +8 -1
- package/dist/dataLayer/schemaDescribe.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/json/systemSchema.json +52 -0
- package/dist/resources/DatabaseTransaction.d.ts +55 -0
- package/dist/resources/DatabaseTransaction.js +459 -45
- package/dist/resources/DatabaseTransaction.js.map +1 -1
- package/dist/resources/LMDBTransaction.js +22 -4
- package/dist/resources/LMDBTransaction.js.map +1 -1
- package/dist/resources/PrimaryRocksDatabase.d.ts +1 -0
- package/dist/resources/PrimaryRocksDatabase.js +29 -0
- package/dist/resources/PrimaryRocksDatabase.js.map +1 -1
- package/dist/resources/RecordEncoder.d.ts +20 -0
- package/dist/resources/RecordEncoder.js +94 -9
- package/dist/resources/RecordEncoder.js.map +1 -1
- package/dist/resources/RequestTarget.d.ts +2 -0
- package/dist/resources/RequestTarget.js.map +1 -1
- package/dist/resources/Resource.js +20 -11
- package/dist/resources/Resource.js.map +1 -1
- package/dist/resources/ResourceInterface.d.ts +20 -1
- package/dist/resources/ResourceInterface.js.map +1 -1
- package/dist/resources/RocksIndexStore.d.ts +6 -1
- package/dist/resources/RocksIndexStore.js +24 -9
- package/dist/resources/RocksIndexStore.js.map +1 -1
- package/dist/resources/RocksTransactionLogStore.d.ts +14 -1
- package/dist/resources/RocksTransactionLogStore.js +57 -17
- package/dist/resources/RocksTransactionLogStore.js.map +1 -1
- package/dist/resources/Table.d.ts +112 -8
- package/dist/resources/Table.js +1073 -191
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/auditStore.d.ts +11 -2
- package/dist/resources/auditStore.js +325 -71
- package/dist/resources/auditStore.js.map +1 -1
- package/dist/resources/blob.d.ts +129 -9
- package/dist/resources/blob.js +992 -114
- package/dist/resources/blob.js.map +1 -1
- package/dist/resources/branchDatabase.d.ts +48 -0
- package/dist/resources/branchDatabase.js +892 -0
- package/dist/resources/branchDatabase.js.map +1 -0
- package/dist/resources/crdt.js +50 -12
- package/dist/resources/crdt.js.map +1 -1
- package/dist/resources/databases.d.ts +150 -0
- package/dist/resources/databases.js +1200 -239
- package/dist/resources/databases.js.map +1 -1
- package/dist/resources/defineTable.d.ts +10 -2
- package/dist/resources/defineTable.js +9 -1
- package/dist/resources/defineTable.js.map +1 -1
- package/dist/resources/graphql.d.ts +1 -1
- package/dist/resources/graphql.js +50 -15
- package/dist/resources/graphql.js.map +1 -1
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +1 -0
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +6 -2
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
- package/dist/resources/longLivedTransactions.d.ts +71 -0
- package/dist/resources/longLivedTransactions.js +358 -0
- package/dist/resources/longLivedTransactions.js.map +1 -0
- package/dist/resources/models/backendRegistry.d.ts +26 -0
- package/dist/resources/models/backendRegistry.js +60 -2
- package/dist/resources/models/backendRegistry.js.map +1 -1
- package/dist/resources/models/bootstrap.d.ts +33 -1
- package/dist/resources/models/bootstrap.js +416 -31
- package/dist/resources/models/bootstrap.js.map +1 -1
- package/dist/resources/recordLock.d.ts +80 -0
- package/dist/resources/recordLock.js +184 -0
- package/dist/resources/recordLock.js.map +1 -0
- package/dist/resources/replayLogs.d.ts +14 -1
- package/dist/resources/replayLogs.js +152 -24
- package/dist/resources/replayLogs.js.map +1 -1
- package/dist/resources/replayLogsGuards.d.ts +94 -7
- package/dist/resources/replayLogsGuards.js +111 -7
- package/dist/resources/replayLogsGuards.js.map +1 -1
- package/dist/resources/search.js +158 -6
- package/dist/resources/search.js.map +1 -1
- package/dist/resources/transactionBroadcast.d.ts +1 -1
- package/dist/resources/transactionBroadcast.js +2 -2
- package/dist/resources/transactionBroadcast.js.map +1 -1
- package/dist/security/auth.js +61 -30
- package/dist/security/auth.js.map +1 -1
- package/dist/security/authn/oidc/claims.d.ts +22 -0
- package/dist/security/authn/oidc/claims.js +71 -0
- package/dist/security/authn/oidc/claims.js.map +1 -0
- package/dist/security/authn/oidc/identityToken.d.ts +27 -0
- package/dist/security/authn/oidc/identityToken.js +111 -0
- package/dist/security/authn/oidc/identityToken.js.map +1 -0
- package/dist/security/authn/oidc/jwks.d.ts +25 -0
- package/dist/security/authn/oidc/jwks.js +261 -0
- package/dist/security/authn/oidc/jwks.js.map +1 -0
- package/dist/security/authn/oidc/providers/generic.d.ts +13 -0
- package/dist/security/authn/oidc/providers/generic.js +34 -0
- package/dist/security/authn/oidc/providers/generic.js.map +1 -0
- package/dist/security/authn/oidc/providers/githubActions.d.ts +11 -0
- package/dist/security/authn/oidc/providers/githubActions.js +129 -0
- package/dist/security/authn/oidc/providers/githubActions.js.map +1 -0
- package/dist/security/authn/oidc/providers/index.d.ts +37 -0
- package/dist/security/authn/oidc/providers/index.js +24 -0
- package/dist/security/authn/oidc/providers/index.js.map +1 -0
- package/dist/security/authn/oidc/tokenExchange.d.ts +12 -0
- package/dist/security/authn/oidc/tokenExchange.js +306 -0
- package/dist/security/authn/oidc/tokenExchange.js.map +1 -0
- package/dist/security/authn/oidc/trustPolicyOperations.d.ts +49 -0
- package/dist/security/authn/oidc/trustPolicyOperations.js +358 -0
- package/dist/security/authn/oidc/trustPolicyOperations.js.map +1 -0
- package/dist/security/authn/oidc/types.d.ts +38 -0
- package/dist/security/authn/oidc/types.js +6 -0
- package/dist/security/authn/oidc/types.js.map +1 -0
- package/dist/security/certificateVerification/index.js +40 -11
- package/dist/security/certificateVerification/index.js.map +1 -1
- package/dist/security/certificateVerification/trustedIssuers.d.ts +24 -0
- package/dist/security/certificateVerification/trustedIssuers.js +79 -0
- package/dist/security/certificateVerification/trustedIssuers.js.map +1 -0
- package/dist/security/certificateVerification/types.d.ts +1 -0
- package/dist/security/credentialProvenance.d.ts +35 -0
- package/dist/security/credentialProvenance.js +51 -0
- package/dist/security/credentialProvenance.js.map +1 -0
- package/dist/security/credentialRejection.d.ts +4 -0
- package/dist/security/credentialRejection.js +24 -0
- package/dist/security/credentialRejection.js.map +1 -0
- package/dist/security/deferredAuthentication.d.ts +36 -0
- package/dist/security/deferredAuthentication.js +70 -0
- package/dist/security/deferredAuthentication.js.map +1 -0
- package/dist/security/impersonation.d.ts +21 -0
- package/dist/security/impersonation.js +108 -9
- package/dist/security/impersonation.js.map +1 -1
- package/dist/security/jsLoader.d.ts +6 -0
- package/dist/security/jsLoader.js +75 -15
- package/dist/security/jsLoader.js.map +1 -1
- package/dist/security/keys.js +301 -71
- package/dist/security/keys.js.map +1 -1
- package/dist/security/operationScope.d.ts +21 -0
- package/dist/security/operationScope.js +36 -0
- package/dist/security/operationScope.js.map +1 -0
- package/dist/security/permissionsTranslator.js +21 -0
- package/dist/security/permissionsTranslator.js.map +1 -1
- package/dist/security/tokenAuthentication.d.ts +19 -1
- package/dist/security/tokenAuthentication.js +191 -10
- package/dist/security/tokenAuthentication.js.map +1 -1
- package/dist/security/user.js +4 -3
- package/dist/security/user.js.map +1 -1
- package/dist/server/DurableSubscriptionsSession.d.ts +2 -2
- package/dist/server/DurableSubscriptionsSession.js +67 -10
- package/dist/server/DurableSubscriptionsSession.js.map +1 -1
- package/dist/server/REST.js +73 -0
- package/dist/server/REST.js.map +1 -1
- package/dist/server/graphqlQuerying.js +4 -0
- package/dist/server/graphqlQuerying.js.map +1 -1
- package/dist/server/http.d.ts +11 -0
- package/dist/server/http.js +88 -15
- package/dist/server/http.js.map +1 -1
- package/dist/server/itc/serverHandlers.js +8 -1
- package/dist/server/itc/serverHandlers.js.map +1 -1
- package/dist/server/jobs/jobProcess.js +6 -2
- package/dist/server/jobs/jobProcess.js.map +1 -1
- package/dist/server/jobs/jobs.js +4 -1
- package/dist/server/jobs/jobs.js.map +1 -1
- package/dist/server/liveSubscriptionAuth.d.ts +26 -4
- package/dist/server/liveSubscriptionAuth.js +105 -39
- package/dist/server/liveSubscriptionAuth.js.map +1 -1
- package/dist/server/loadRootComponents.js +49 -10
- package/dist/server/loadRootComponents.js.map +1 -1
- package/dist/server/mqtt.d.ts +2 -0
- package/dist/server/mqtt.js +165 -30
- package/dist/server/mqtt.js.map +1 -1
- package/dist/server/nodeName.d.ts +2 -0
- package/dist/server/nodeName.js +107 -23
- package/dist/server/nodeName.js.map +1 -1
- package/dist/server/serverHelpers/Headers.d.ts +25 -0
- package/dist/server/serverHelpers/Headers.js +139 -1
- package/dist/server/serverHelpers/Headers.js.map +1 -1
- package/dist/server/serverHelpers/contentTypes.d.ts +9 -0
- package/dist/server/serverHelpers/contentTypes.js +32 -25
- package/dist/server/serverHelpers/contentTypes.js.map +1 -1
- package/dist/server/serverHelpers/deployValidationState.d.ts +3 -0
- package/dist/server/serverHelpers/deployValidationState.js +9 -19
- package/dist/server/serverHelpers/deployValidationState.js.map +1 -1
- package/dist/server/serverHelpers/operationAuthorizationState.d.ts +12 -0
- package/dist/server/serverHelpers/operationAuthorizationState.js +24 -2
- package/dist/server/serverHelpers/operationAuthorizationState.js.map +1 -1
- package/dist/server/serverHelpers/registeredOperations.d.ts +5 -4
- package/dist/server/serverHelpers/registeredOperations.js +74 -21
- package/dist/server/serverHelpers/registeredOperations.js.map +1 -1
- package/dist/server/serverHelpers/requestSanitization.d.ts +11 -0
- package/dist/server/serverHelpers/requestSanitization.js +20 -0
- package/dist/server/serverHelpers/requestSanitization.js.map +1 -0
- package/dist/server/serverHelpers/serverHandlers.js +6 -3
- package/dist/server/serverHelpers/serverHandlers.js.map +1 -1
- package/dist/server/serverHelpers/serverUtilities.d.ts +18 -0
- package/dist/server/serverHelpers/serverUtilities.js +90 -20
- package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
- package/dist/server/serverHelpers/sharedMessageEncoding.d.ts +67 -0
- package/dist/server/serverHelpers/sharedMessageEncoding.js +280 -0
- package/dist/server/serverHelpers/sharedMessageEncoding.js.map +1 -0
- package/dist/server/serverHelpers/uwsServer.js +19 -1
- package/dist/server/serverHelpers/uwsServer.js.map +1 -1
- package/dist/server/static.js +24 -28
- package/dist/server/static.js.map +1 -1
- package/dist/server/storageReclamation.d.ts +12 -0
- package/dist/server/storageReclamation.js +26 -0
- package/dist/server/storageReclamation.js.map +1 -1
- package/dist/server/threads/itc.d.ts +7 -2
- package/dist/server/threads/itc.js +5 -1
- package/dist/server/threads/itc.js.map +1 -1
- package/dist/server/threads/manageThreads.d.ts +26 -3
- package/dist/server/threads/manageThreads.js +517 -65
- package/dist/server/threads/manageThreads.js.map +1 -1
- package/dist/server/threads/socketRouter.js +89 -26
- package/dist/server/threads/socketRouter.js.map +1 -1
- package/dist/server/threads/threadHeapMemory.d.ts +2 -0
- package/dist/server/threads/threadHeapMemory.js +31 -0
- package/dist/server/threads/threadHeapMemory.js.map +1 -0
- package/dist/server/threads/threadServer.js +46 -15
- package/dist/server/threads/threadServer.js.map +1 -1
- package/dist/sqlEngine/config.d.ts +1 -3
- package/dist/sqlEngine/config.js +19 -16
- package/dist/sqlEngine/config.js.map +1 -1
- package/dist/sqlTranslator/index.d.ts +1 -1
- package/dist/sqlTranslator/index.js +30 -7
- package/dist/sqlTranslator/index.js.map +1 -1
- package/dist/upgrade/directives/5-3-0.d.ts +7 -0
- package/dist/upgrade/directives/5-3-0.js +148 -0
- package/dist/upgrade/directives/5-3-0.js.map +1 -0
- package/dist/upgrade/directives/directivesController.js +2 -1
- package/dist/upgrade/directives/directivesController.js.map +1 -1
- package/dist/utility/OperationFunctionCaller.js +2 -1
- package/dist/utility/OperationFunctionCaller.js.map +1 -1
- package/dist/utility/common_utils.d.ts +16 -0
- package/dist/utility/common_utils.js +32 -6
- package/dist/utility/common_utils.js.map +1 -1
- package/dist/utility/componentNames.d.ts +8 -0
- package/dist/utility/componentNames.js +12 -1
- package/dist/utility/componentNames.js.map +1 -1
- package/dist/utility/environment/environmentManager.js +3 -6
- package/dist/utility/environment/environmentManager.js.map +1 -1
- package/dist/utility/environment/systemInformation.d.ts +1 -0
- package/dist/utility/environment/systemInformation.js +1 -0
- package/dist/utility/environment/systemInformation.js.map +1 -1
- package/dist/utility/errors/commonErrors.d.ts +2 -0
- package/dist/utility/errors/commonErrors.js +2 -0
- package/dist/utility/errors/commonErrors.js.map +1 -1
- package/dist/utility/errors/hdbError.d.ts +17 -0
- package/dist/utility/errors/hdbError.js +30 -1
- package/dist/utility/errors/hdbError.js.map +1 -1
- package/dist/utility/globalSchema.d.ts +18 -0
- package/dist/utility/hdbTerms.d.ts +16 -0
- package/dist/utility/hdbTerms.js +18 -2
- package/dist/utility/hdbTerms.js.map +1 -1
- package/dist/utility/logging/harper_logger.d.ts +2 -0
- package/dist/utility/logging/harper_logger.js +91 -14
- package/dist/utility/logging/harper_logger.js.map +1 -1
- package/dist/utility/logging/logRotator.js +76 -49
- package/dist/utility/logging/logRotator.js.map +1 -1
- package/dist/utility/nodeIdentity.d.ts +9 -0
- package/dist/utility/nodeIdentity.js +58 -0
- package/dist/utility/nodeIdentity.js.map +1 -0
- package/dist/utility/npmUtilities.js +9 -7
- package/dist/utility/npmUtilities.js.map +1 -1
- package/dist/utility/operationPermissions.d.ts +3 -1
- package/dist/utility/operationPermissions.js +16 -1
- package/dist/utility/operationPermissions.js.map +1 -1
- package/dist/utility/operation_authorization.d.ts +10 -7
- package/dist/utility/operation_authorization.js +212 -41
- package/dist/utility/operation_authorization.js.map +1 -1
- package/dist/utility/watchPath.d.ts +29 -0
- package/dist/utility/watchPath.js +68 -0
- package/dist/utility/watchPath.js.map +1 -0
- package/dist/utility/watcherFallback.d.ts +86 -0
- package/dist/utility/watcherFallback.js +278 -1
- package/dist/utility/watcherFallback.js.map +1 -1
- package/dist/validation/configValidator.d.ts +12 -0
- package/dist/validation/configValidator.js +199 -72
- package/dist/validation/configValidator.js.map +1 -1
- package/dist/validation/installValidator.js +12 -0
- package/dist/validation/installValidator.js.map +1 -1
- package/dist/validation/validationWrapper.d.ts +11 -0
- package/dist/validation/validationWrapper.js +16 -3
- package/dist/validation/validationWrapper.js.map +1 -1
- package/index.ts +2 -0
- package/json/systemSchema.json +52 -0
- package/npm-shrinkwrap.json +196 -194
- package/package.json +7 -6
- package/resources/DESIGN.md +114 -52
- package/resources/DatabaseTransaction.ts +521 -43
- package/resources/LMDBTransaction.ts +26 -4
- package/resources/PrimaryRocksDatabase.ts +28 -1
- package/resources/RecordEncoder.ts +103 -8
- package/resources/RequestTarget.ts +2 -0
- package/resources/Resource.ts +17 -9
- package/resources/ResourceInterface.ts +23 -0
- package/resources/RocksIndexStore.ts +30 -9
- package/resources/RocksTransactionLogStore.ts +78 -21
- package/resources/Table.ts +1110 -159
- package/resources/auditStore.ts +331 -73
- package/resources/blob.ts +1029 -110
- package/resources/branchDatabase.ts +941 -0
- package/resources/crdt.ts +76 -12
- package/resources/databases.ts +1310 -252
- package/resources/defineTable.ts +18 -2
- package/resources/graphql.ts +70 -16
- package/resources/indexes/HierarchicalNavigableSmallWorld.ts +6 -2
- package/resources/longLivedTransactions.ts +360 -0
- package/resources/models/backendRegistry.ts +84 -2
- package/resources/models/bootstrap.ts +473 -28
- package/resources/recordLock.ts +253 -0
- package/resources/replayLogs.ts +147 -26
- package/resources/replayLogsGuards.ts +171 -8
- package/resources/search.ts +154 -7
- package/resources/transactionBroadcast.ts +3 -3
- package/security/auth.ts +68 -29
- package/security/authn/oidc/claims.ts +72 -0
- package/security/authn/oidc/identityToken.ts +129 -0
- package/security/authn/oidc/jwks.ts +260 -0
- package/security/authn/oidc/providers/generic.ts +40 -0
- package/security/authn/oidc/providers/githubActions.ts +137 -0
- package/security/authn/oidc/providers/index.ts +52 -0
- package/security/authn/oidc/tokenExchange.ts +300 -0
- package/security/authn/oidc/trustPolicyOperations.ts +343 -0
- package/security/authn/oidc/types.ts +41 -0
- package/security/certificateVerification/index.ts +54 -13
- package/security/certificateVerification/trustedIssuers.ts +76 -0
- package/security/certificateVerification/types.ts +1 -0
- package/security/credentialProvenance.ts +47 -0
- package/security/credentialRejection.ts +22 -0
- package/security/deferredAuthentication.ts +71 -0
- package/security/impersonation.ts +117 -12
- package/security/jsLoader.ts +81 -18
- package/security/keys.ts +298 -72
- package/security/operationScope.ts +33 -0
- package/security/permissionsTranslator.js +23 -0
- package/security/tokenAuthentication.ts +233 -12
- package/security/user.ts +4 -3
- package/server/DESIGN.md +183 -16
- package/server/DurableSubscriptionsSession.ts +71 -11
- package/server/REST.ts +79 -1
- package/server/graphqlQuerying.ts +4 -0
- package/server/http.ts +99 -18
- package/server/itc/serverHandlers.js +8 -1
- package/server/jobs/jobProcess.ts +8 -2
- package/server/jobs/jobs.ts +4 -1
- package/server/liveSubscriptionAuth.ts +129 -46
- package/server/loadRootComponents.js +50 -8
- package/server/mqtt.ts +179 -38
- package/server/nodeName.ts +103 -21
- package/server/serverHelpers/Headers.ts +131 -0
- package/server/serverHelpers/contentTypes.ts +29 -21
- package/server/serverHelpers/deployValidationState.ts +24 -13
- package/server/serverHelpers/operationAuthorizationState.ts +34 -3
- package/server/serverHelpers/registeredOperations.ts +79 -22
- package/server/serverHelpers/requestSanitization.ts +15 -0
- package/server/serverHelpers/serverHandlers.js +6 -3
- package/server/serverHelpers/serverUtilities.ts +104 -31
- package/server/serverHelpers/sharedMessageEncoding.ts +307 -0
- package/server/serverHelpers/uwsServer.ts +17 -2
- package/server/static.ts +23 -29
- package/server/storageReclamation.ts +23 -0
- package/server/threads/itc.js +11 -1
- package/server/threads/manageThreads.js +526 -56
- package/server/threads/socketRouter.ts +81 -26
- package/server/threads/threadHeapMemory.ts +26 -0
- package/server/threads/threadServer.js +43 -15
- package/sqlTranslator/index.ts +31 -8
- package/studio/web/assets/Chat-BnCBegQz.js +2267 -0
- package/studio/web/assets/FloatingChat-CoDW1ySS.js +23 -0
- package/studio/web/assets/{abnfDiagram-VCTEODGH-C0_BAZyO.js → abnfDiagram-VCTEODGH-B0BebmD2.js} +1 -1
- package/studio/web/assets/{alertDialog-DIHt7Z0r.js → alertDialog-CQyAJJhl.js} +1 -1
- package/studio/web/assets/{apiToken-c3Rd-w6g.js → apiToken-Bwk5BLXW.js} +1 -1
- package/studio/web/assets/applications-DHxGi7JH.js +296 -0
- package/studio/web/assets/architecture-7GRP2DOG-LB-MLAAb.js +1 -0
- package/studio/web/assets/{architectureDiagram-5GKGNRK7-BWzrASgm.js → architectureDiagram-5GKGNRK7-7SW3GD-K.js} +1 -1
- package/studio/web/assets/authStore-C3Nfubqr.js +3 -0
- package/studio/web/assets/{blockDiagram-NRAW4CY4-BdJX9Khj.js → blockDiagram-I7D4REHJ-BqguiadH.js} +2 -2
- package/studio/web/assets/{button-DhiX-njv.js → button-BIsUKRZq.js} +2 -2
- package/studio/web/assets/{c4Diagram-UCG6FXSJ-CI6MzGmQ.js → c4Diagram-7LVT6UL2-LBNf8t_X.js} +1 -1
- package/studio/web/assets/channel-yictG-U-.js +1 -0
- package/studio/web/assets/{chevron-up-Df2c8uoU.js → chevron-up-DtKGqDn3.js} +1 -1
- package/studio/web/assets/{chunk-TEH6E4GO-P87k5mNi.js → chunk-4HAMMTFA-DWtTut21.js} +1 -1
- package/studio/web/assets/{chunk-75Z2AOVW-BT8tVmks.js → chunk-75Z2AOVW-QGQD6th2.js} +1 -1
- package/studio/web/assets/{chunk-DU6HZSFF-9kAOOmI6.js → chunk-DU6HZSFF-Chq20Ba5.js} +1 -1
- package/studio/web/assets/{chunk-F27PBJKO-BW7ao8AY.js → chunk-F27PBJKO-BVA5EPhV.js} +1 -1
- package/studio/web/assets/{chunk-GMAD6QVW-BNyXpoQO.js → chunk-GMAD6QVW-BeS7S07A.js} +1 -1
- package/studio/web/assets/{chunk-OBVCFTLP-D4wWOqDQ.js → chunk-GVQU2GXP-sbwVIQ8i.js} +1 -1
- package/studio/web/assets/{chunk-G27WJ6UU-COyLMcgK.js → chunk-IMKFNOWR-Bnh3tAVd.js} +1 -1
- package/studio/web/assets/{chunk-JQ64N6SF-Cyz1IeLf.js → chunk-L3NEJ4N5-COfUyKII.js} +1 -1
- package/studio/web/assets/chunk-OSK3NFVY-ByciRftO.js +10 -0
- package/studio/web/assets/{chunk-P2QGCYS3-DmIFY4d7.js → chunk-P2QGCYS3-CP1VhG_c.js} +1 -1
- package/studio/web/assets/{chunk-POPQ4Y6H-BPrvMyKz.js → chunk-POPQ4Y6H-ClWhhkwW.js} +1 -1
- package/studio/web/assets/{chunk-PWAF6VOD-2zB6IW9i.js → chunk-PWAF6VOD-1z1THyS5.js} +1 -1
- package/studio/web/assets/{chunk-RHFEMEQ7-2FgyI8YU.js → chunk-SHT3W25Y-LpQkMsah.js} +2 -2
- package/studio/web/assets/{chunk-SVP7TREG-FwtbH2QC.js → chunk-SVP7TREG-jtdAHw0S.js} +1 -1
- package/studio/web/assets/{chunk-LCL6LL3I-HOzK_ppE.js → chunk-TICWLB2K-VOwzetX-.js} +1 -1
- package/studio/web/assets/classDiagram-ZZMXUADV-VaEwSy_g.js +1 -0
- package/studio/web/assets/classDiagram-v2-VYDZK3BY-VaEwSy_g.js +1 -0
- package/studio/web/assets/{createLucideIcon-BKGPfjm2.js → createLucideIcon-CzW9508A.js} +1 -1
- package/studio/web/assets/{cssMode-CEN2mzSA.js → cssMode-s0cWI-_M.js} +1 -1
- package/studio/web/assets/{cynefin-OW5HDTMX-BRkpLFQV.js → cynefin-OW5HDTMX-BbdbCvub.js} +1 -1
- package/studio/web/assets/{cynefinDiagram-5FMLGOSQ-CHT1DaX6.js → cynefinDiagram-5FMLGOSQ-TP-aIqbt.js} +1 -1
- package/studio/web/assets/{dagre-3AP2YEHR-DpUXBh63.js → dagre-GXQ25YYZ-DShnGpGo.js} +1 -1
- package/studio/web/assets/{diagram-S7CK7UJ4-BuymVFZT.js → diagram-S7CK7UJ4-aoCVTtcy.js} +1 -1
- package/studio/web/assets/{diagram-UQ7AKVKN-CyP148RM.js → diagram-UQ7AKVKN-DglXtQ6x.js} +1 -1
- package/studio/web/assets/{diagram-VSXAHHWV-CoCAg3M9.js → diagram-VSXAHHWV-fhEdmkwM.js} +1 -1
- package/studio/web/assets/{diagram-VX7I27RA-BpOqCFca.js → diagram-VX7I27RA-DccVJet6.js} +1 -1
- package/studio/web/assets/{diagram-Z3DM3KII-Bfpw7Vbj.js → diagram-Z3DM3KII-D-RyJJb7.js} +1 -1
- package/studio/web/assets/{dialog-CBf0Mr1d.js → dialog-Cn2uWgD4.js} +1 -1
- package/studio/web/assets/{dist-lkA3O3eM.js → dist-DP8UjMB_.js} +1 -1
- package/studio/web/assets/{download-BtTOBem-.js → download-B5T5r7ss.js} +1 -1
- package/studio/web/assets/{ebnfDiagram-PWID7BFC-DS_6aWqL.js → ebnfDiagram-PWID7BFC-DJGpIpz_.js} +1 -1
- package/studio/web/assets/{editor-D8oDeCTL.js → editor-DNcRHK54.js} +1 -1
- package/studio/web/assets/{erDiagram-SSCWMZ5O-DJNk6Fgw.js → erDiagram-RLTQ6QDP-CIfNlgkC.js} +1 -1
- package/studio/web/assets/eventmodeling-NTZA5JFV-CLxnp2CR.js +1 -0
- package/studio/web/assets/flowDiagram-HODETNUW-BIbhmz9f.js +1 -0
- package/studio/web/assets/{ganttDiagram-EL5Y4UJY-2pOExxMY.js → ganttDiagram-EL5Y4UJY-BxToTzzD.js} +1 -1
- package/studio/web/assets/{getAnalytics-D4LKGeVy.js → getAnalytics-GHK8ORfM.js} +1 -1
- package/studio/web/assets/{gitGraph-4MIJSDKK-CH5ZxwzF.js → gitGraph-4MIJSDKK-D2s2w8lE.js} +1 -1
- package/studio/web/assets/{gitGraphDiagram-WWUBYQGX-DVIsIhbO.js → gitGraphDiagram-WWUBYQGX-Dwntd4-x.js} +1 -1
- package/studio/web/assets/{html-u3vOg7LJ.js → html-Bdssedlg.js} +1 -1
- package/studio/web/assets/{htmlMode-DyO31v-P.js → htmlMode-CoDlJ3fw.js} +1 -1
- package/studio/web/assets/{index-Cxj2_wsl.css → index-7RMEgVG1.css} +1 -1
- package/studio/web/assets/index-D6sxmFLR.js +824 -0
- package/studio/web/assets/index.lazy-tmU5BS8s.js +2 -0
- package/studio/web/assets/{info-A6RAGUB7-CPQfTnaG.js → info-A6RAGUB7-DYjkvb0C.js} +1 -1
- package/studio/web/assets/{infoDiagram-RXCK75RN-DlwLYlwm.js → infoDiagram-27XIBGKW-Bnp1FJE5.js} +1 -1
- package/studio/web/assets/{ishikawaDiagram-5VMMS53U-BRXRp29U.js → ishikawaDiagram-5VMMS53U-D9Xh2r6X.js} +1 -1
- package/studio/web/assets/{javascript-CUvxOyTC.js → javascript-B8meVSTH.js} +1 -1
- package/studio/web/assets/{journeyDiagram-EYS64GPL-B0ou8k0n.js → journeyDiagram-3NMN7TZE-CokIi6ll.js} +2 -2
- package/studio/web/assets/{jsonMode-f_IwbF3D.js → jsonMode-DpIPd35T.js} +1 -1
- package/studio/web/assets/{kanban-definition-3QL26DDD-uYg7iYzp.js → kanban-definition-UXKFOSKX-CukSFJfX.js} +1 -1
- package/studio/web/assets/{languageServices-DXtZ6rEF.js → languageServices-C_5FMJzQ.js} +1 -1
- package/studio/web/assets/{lspLanguageFeatures-B4pCF1zO.js → lspLanguageFeatures-BIzNBzPK.js} +1 -1
- package/studio/web/assets/{mermaid-parser.core-Ck-fC8b7.js → mermaid-parser.core-BlEsOWNO.js} +3 -3
- package/studio/web/assets/{mermaid.core-CP8aNNYm.js → mermaid.core-BlkGaMIH.js} +5 -5
- package/studio/web/assets/{mindmap-definition-FBJOCRG2-CgTZ-rit.js → mindmap-definition-YA3MSWOX-IprMc_0j.js} +1 -1
- package/studio/web/assets/{notifications-D3tIQ4sg.js → notifications-CQf18QKb.js} +1 -1
- package/studio/web/assets/notifications-CvZivSbh.js +1 -0
- package/studio/web/assets/{packet-AYTQ26CC-DEyoPtPb.js → packet-AYTQ26CC-Bi3V04Zi.js} +1 -1
- package/studio/web/assets/{pegDiagram-XKGWAZYB-DrD-7sD9.js → pegDiagram-XKGWAZYB-BNuPDLZY.js} +1 -1
- package/studio/web/assets/{pie-WAS4IAKB-wjj-EI1d.js → pie-WAS4IAKB-_6DoDbng.js} +1 -1
- package/studio/web/assets/{pieDiagram-E7YTZNPT-GntqDCzv.js → pieDiagram-E7YTZNPT-DqNb6Ht2.js} +1 -1
- package/studio/web/assets/{profile-DZWU7MgT.js → profile-DdOwtntb.js} +1 -1
- package/studio/web/assets/{quadrantDiagram-AXDQQJYC-0UeqXQGd.js → quadrantDiagram-AXDQQJYC-BGH9E2YR.js} +1 -1
- package/studio/web/assets/{radar-RG4KPBEZ-DFSA5h7k.js → radar-RG4KPBEZ-DDdVczcL.js} +1 -1
- package/studio/web/assets/{railroad-74A4TZTK-CaOUG9wR.js → railroad-74A4TZTK-BJUP4Jds.js} +1 -1
- package/studio/web/assets/railroad-abnf-HS5TGJTU-Bm3L1L0h.js +1 -0
- package/studio/web/assets/railroad-ebnf-LZEXJU2U-CKzLGlkw.js +1 -0
- package/studio/web/assets/railroad-peg-WCYAUIDC-S8xLjslx.js +1 -0
- package/studio/web/assets/{railroadDiagram-O6MQD6OU-yHUELZaV.js → railroadDiagram-O6MQD6OU-DGTPh2KZ.js} +1 -1
- package/studio/web/assets/{regions-CkyurXzE.js → regions-n69fwagr.js} +1 -1
- package/studio/web/assets/{register-BUyhWjBO.js → register-PfWTCXWB.js} +3 -3
- package/studio/web/assets/{requirementDiagram-EFPCY7ZU-DNEGFjuW.js → requirementDiagram-BXWQKSXE-BJnO6uLz.js} +1 -1
- package/studio/web/assets/{sankeyDiagram-P5KCCOFB-DpyAmSVR.js → sankeyDiagram-P5KCCOFB-0vSOdymH.js} +1 -1
- package/studio/web/assets/{sequenceDiagram-WJ2MYXX4-TyaT7xNk.js → sequenceDiagram-WJ2MYXX4-hETizDWE.js} +1 -1
- package/studio/web/assets/{setComponentFile-CeyKSZAa.js → setComponentFile-Bg6O7X0S.js} +1 -1
- package/studio/web/assets/{setup-D2kn7cAA.js → setup-CUx_aUDl.js} +2 -2
- package/studio/web/assets/{stateDiagram-HBIQ2CUA-CeEdTArZ.js → stateDiagram-D77RDMKH-CdYQ_KtC.js} +1 -1
- package/studio/web/assets/stateDiagram-v2-MP3YSRHH-CdKuzQMT.js +1 -0
- package/studio/web/assets/status-D7BVKqX9.js +61 -0
- package/studio/web/assets/{swimlanes-XN3QIQJK-B54FmF46.js → swimlanes-42K2YHIH-B8cHIpU4.js} +1 -1
- package/studio/web/assets/swimlanesDiagram-VR7AAH4N-DmOSJwaH.js +8 -0
- package/studio/web/assets/{tabs-B_G5zscN.js → tabs-BrHu7gJi.js} +1 -1
- package/studio/web/assets/{timeline-definition-24CTP7MA-D-a9ujbo.js → timeline-definition-24CTP7MA-BJWYSXqF.js} +1 -1
- package/studio/web/assets/{toggleHighContrast-C0UW6rI2.js → toggleHighContrast-DBSyXzMr.js} +1 -1
- package/studio/web/assets/{treeView-Q6P3EWNA-CrW_6JnS.js → treeView-Q6P3EWNA-qxe_v6CQ.js} +1 -1
- package/studio/web/assets/{treemap-WGGIJYW6-BxyYLdP_.js → treemap-WGGIJYW6-dDo97XXF.js} +1 -1
- package/studio/web/assets/{tsMode-DBC0zmDx.js → tsMode-BByKCjBS.js} +1 -1
- package/studio/web/assets/{typescript-DApRQir3.js → typescript-DDLnLpw9.js} +1 -1
- package/studio/web/assets/{useEntityRestURL-DB6JStU1.js → useEntityRestURL-31CHGaHk.js} +1 -1
- package/studio/web/assets/{useLocalStorage-Dtj1QS8_.js → useLocalStorage-BqMR3D8_.js} +1 -1
- package/studio/web/assets/vendor-core-c2JRRJpV.js +58 -0
- package/studio/web/assets/vendor-datadog-CLUcJXOo.js +6 -0
- package/studio/web/assets/{vendor-react-Dyj4O3HE.js → vendor-react-CJV_K1u4.js} +1 -1
- package/studio/web/assets/vendor-tanstack-DxzraizX.js +1 -0
- package/studio/web/assets/{vendor-ui-vhu-UHhF.js → vendor-ui-BUjK0h8a.js} +2 -2
- package/studio/web/assets/{vennDiagram-4TSXK5OY-Cy7s7Mpy.js → vennDiagram-4TSXK5OY-A3i-lCdl.js} +1 -1
- package/studio/web/assets/{wardley-WFR3VGLG-BeBL35g2.js → wardley-WFR3VGLG-B0ik-_6g.js} +1 -1
- package/studio/web/assets/{wardleyDiagram-VM6X3IG4-BylmIGSg.js → wardleyDiagram-VM6X3IG4-CjrkKWUR.js} +1 -1
- package/studio/web/assets/{workers-C0bFIedw.js → workers-pR3jRY9D.js} +1 -1
- package/studio/web/assets/x-DIzaLEdK.js +1 -0
- package/studio/web/assets/{xml-HWd01lU-.js → xml-2iRnMhQO.js} +1 -1
- package/studio/web/assets/{xychartDiagram-S5SC5T6Z-CoKALMXr.js → xychartDiagram-S5SC5T6Z-Biok4GYV.js} +1 -1
- package/studio/web/assets/{yaml-CIH0Nt-h.js → yaml-Bf92gJpd.js} +1 -1
- package/studio/web/index.html +14 -14
- package/upgrade/directives/5-3-0.ts +132 -0
- package/upgrade/directives/directivesController.ts +2 -1
- package/utility/OperationFunctionCaller.ts +2 -1
- package/utility/common_utils.ts +30 -5
- package/utility/componentNames.ts +12 -0
- package/utility/environment/environmentManager.ts +3 -7
- package/utility/environment/systemInformation.ts +7 -0
- package/utility/errors/commonErrors.ts +4 -0
- package/utility/errors/hdbError.ts +29 -0
- package/utility/hdbTerms.ts +17 -0
- package/utility/logging/harper_logger.ts +87 -14
- package/utility/logging/logRotator.ts +72 -45
- package/utility/nodeIdentity.ts +45 -0
- package/utility/npmUtilities.ts +10 -8
- package/utility/operationPermissions.ts +18 -1
- package/utility/operation_authorization.ts +231 -42
- package/utility/watchPath.ts +63 -0
- package/utility/watcherFallback.ts +270 -0
- package/validation/configValidator.ts +209 -72
- package/validation/installValidator.ts +15 -0
- package/validation/validationWrapper.ts +18 -4
- package/studio/web/assets/Chat-JpO8EtUu.js +0 -2067
- package/studio/web/assets/FloatingChat-Bcj3xSZu.js +0 -23
- package/studio/web/assets/applications-ByqLRKyZ.js +0 -296
- package/studio/web/assets/architecture-7GRP2DOG-DNdx5tEU.js +0 -1
- package/studio/web/assets/authStore-qKmCZcaf.js +0 -3
- package/studio/web/assets/channel-DtCV8PTL.js +0 -1
- package/studio/web/assets/chunk-R7TYR2AO-Irip67yr.js +0 -10
- package/studio/web/assets/classDiagram-DTDB5LWJ-DbO_dCNE.js +0 -1
- package/studio/web/assets/classDiagram-v2-JRS7N3AN-DbO_dCNE.js +0 -1
- package/studio/web/assets/eventmodeling-NTZA5JFV-5jbe4A5P.js +0 -1
- package/studio/web/assets/flowDiagram-A5DVABFB-Dp9Ezlow.js +0 -1
- package/studio/web/assets/index-aSt5tY-L.js +0 -824
- package/studio/web/assets/index.lazy-B9jiPwT8.js +0 -2
- package/studio/web/assets/notifications-CUoYgU98.js +0 -1
- package/studio/web/assets/railroad-abnf-HS5TGJTU-Bc0Qi0WH.js +0 -1
- package/studio/web/assets/railroad-ebnf-LZEXJU2U-G8rVVZ2C.js +0 -1
- package/studio/web/assets/railroad-peg-WCYAUIDC-CrehKBhC.js +0 -1
- package/studio/web/assets/stateDiagram-v2-4QOOHH4V-D4tuw9Su.js +0 -1
- package/studio/web/assets/status-D7Xn5ePA.js +0 -61
- package/studio/web/assets/swimlanesDiagram-VK2B7HYN-XOhmNEvq.js +0 -8
- package/studio/web/assets/vendor-core-RCcadM3e.js +0 -73
- package/studio/web/assets/vendor-datadog-BRv-mOv1.js +0 -6
- package/studio/web/assets/vendor-tanstack-BiFWSB3W.js +0 -1
- package/studio/web/assets/x-B9o9hsep.js +0 -1
- /package/studio/web/assets/{sizeCapture-X5ZJPWSS-B0uUizjq.js → sizeCapture-INFHLROL-B0uUizjq.js} +0 -0
package/agent/mcpTools.ts
CHANGED
|
@@ -57,7 +57,7 @@ const AGENT_MCP_TOOLS: Record<string, AgentMcpToolMeta> = {
|
|
|
57
57
|
readOnly: true,
|
|
58
58
|
},
|
|
59
59
|
list_agent_sessions: {
|
|
60
|
-
description: 'List built-in-agent sessions, most
|
|
60
|
+
description: 'List built-in-agent sessions, most recently updated first.',
|
|
61
61
|
inputSchema: {
|
|
62
62
|
type: 'object',
|
|
63
63
|
properties: { limit: { type: 'integer', minimum: 1, description: 'Max sessions to return (default 100).' } },
|
package/agent/session.ts
CHANGED
|
@@ -16,6 +16,20 @@ import type { AgentMessage, AgentRunStatus, AgentSessionRow, ApprovalRequest } f
|
|
|
16
16
|
|
|
17
17
|
let cachedTable: any;
|
|
18
18
|
|
|
19
|
+
/** `listSessions` sorts on `updatedAt`, which Table.search serves only from an index. */
|
|
20
|
+
export const AGENT_SESSION_ATTRIBUTES = [
|
|
21
|
+
{ name: 'session_id', isPrimaryKey: true },
|
|
22
|
+
{ name: 'user', type: 'string', indexed: true },
|
|
23
|
+
{ name: 'status', type: 'string', indexed: true },
|
|
24
|
+
{ name: 'messages' },
|
|
25
|
+
{ name: 'pendingApprovals' },
|
|
26
|
+
{ name: 'model', type: 'string' },
|
|
27
|
+
{ name: 'provider', type: 'string' },
|
|
28
|
+
{ name: 'createdAt', type: 'number', indexed: true },
|
|
29
|
+
{ name: 'updatedAt', type: 'number', indexed: true },
|
|
30
|
+
{ name: 'lastError', type: 'string' },
|
|
31
|
+
];
|
|
32
|
+
|
|
19
33
|
export function getAgentSessionTable(): any {
|
|
20
34
|
if (cachedTable) return cachedTable;
|
|
21
35
|
cachedTable = table({
|
|
@@ -23,18 +37,7 @@ export function getAgentSessionTable(): any {
|
|
|
23
37
|
database: SYSTEM_SCHEMA_NAME,
|
|
24
38
|
audit: true,
|
|
25
39
|
trackDeletes: false,
|
|
26
|
-
attributes:
|
|
27
|
-
{ name: 'session_id', isPrimaryKey: true },
|
|
28
|
-
{ name: 'user', type: 'string', indexed: true },
|
|
29
|
-
{ name: 'status', type: 'string', indexed: true },
|
|
30
|
-
{ name: 'messages' },
|
|
31
|
-
{ name: 'pendingApprovals' },
|
|
32
|
-
{ name: 'model', type: 'string' },
|
|
33
|
-
{ name: 'provider', type: 'string' },
|
|
34
|
-
{ name: 'createdAt', type: 'number', indexed: true },
|
|
35
|
-
{ name: 'updatedAt', type: 'number', indexed: true },
|
|
36
|
-
{ name: 'lastError', type: 'string' },
|
|
37
|
-
],
|
|
40
|
+
attributes: AGENT_SESSION_ATTRIBUTES,
|
|
38
41
|
});
|
|
39
42
|
return cachedTable;
|
|
40
43
|
}
|
|
@@ -77,8 +80,16 @@ export async function getSession(sessionId: string): Promise<AgentSessionRow | u
|
|
|
77
80
|
export async function listSessions(opts: { limit?: number } = {}): Promise<AgentSessionRow[]> {
|
|
78
81
|
const limit = opts.limit ?? 100;
|
|
79
82
|
const out: AgentSessionRow[] = [];
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
// Sort with no conditions on purpose: Table.search pushes an order-aligned pseudo-condition when
|
|
84
|
+
// the sort attribute is indexed, and throws 404 when it is not. Adding a `updatedAt > 0` sentinel
|
|
85
|
+
// to force the index would make conditions non-empty, so losing `indexed` on the attribute would
|
|
86
|
+
// silently degrade to decoding every session (full transcripts) and sorting in memory instead of
|
|
87
|
+
// failing. The sentinel would also drop rows whose updatedAt is absent or 0.
|
|
88
|
+
for await (const row of getAgentSessionTable().search({
|
|
89
|
+
sort: { attribute: 'updatedAt', descending: true },
|
|
90
|
+
limit,
|
|
91
|
+
})) {
|
|
92
|
+
if (row != null) out.push(row as AgentSessionRow);
|
|
82
93
|
}
|
|
83
94
|
return out;
|
|
84
95
|
}
|
package/bin/cliOperations.ts
CHANGED
|
@@ -6,6 +6,7 @@ import * as envMgr from '../utility/environment/environmentManager.ts';
|
|
|
6
6
|
envMgr.initSync();
|
|
7
7
|
import * as terms from '../utility/hdbTerms.ts';
|
|
8
8
|
import { httpRequest } from '../utility/common_utils.ts';
|
|
9
|
+
import { workloadIdentityAvailable, exchangeWorkloadIdentityForToken } from './workloadIdentity.ts';
|
|
9
10
|
import * as fs from 'fs-extra';
|
|
10
11
|
import * as YAML from 'yaml';
|
|
11
12
|
import { Readable } from 'node:stream';
|
|
@@ -55,11 +56,11 @@ const TRANSPORT_ONLY_FIELDS = new Set([
|
|
|
55
56
|
'by_ref',
|
|
56
57
|
'ref',
|
|
57
58
|
'credential',
|
|
58
|
-
// `deploy setup=true`'s token, read off the parsed request by deploySetup and sealed locally.
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
//
|
|
59
|
+
// `deploy setup=true`'s token, read off the parsed request by deploySetup and sealed locally.
|
|
60
|
+
// Stripping it means a mistyped `setup` — which parses as a bare word and falls through to a real
|
|
61
|
+
// deploy — can't carry a PAT to the server. Distinct from `credentials[].token`, which is nested
|
|
62
|
+
// inside a field that IS sent (ingestCredentials seals it server-side) and is only kept out of the
|
|
63
|
+
// operations log. See OPERATIONS_TAKING_A_TOKEN for the one operation this must not apply to.
|
|
63
64
|
'token',
|
|
64
65
|
]);
|
|
65
66
|
|
|
@@ -179,10 +180,24 @@ async function* wrapPackagingStream(stream: Readable, projectPath: string): Asyn
|
|
|
179
180
|
// Build the JSON operation-field set from `req`, dropping the CLI's internal (`_`-prefixed)
|
|
180
181
|
// and transport-only fields so neither the CLI internals nor credentials leak into the
|
|
181
182
|
// request body. Shared by the multipart and legacy-JSON deploy body builders.
|
|
183
|
+
/**
|
|
184
|
+
* Operations whose own request body has a top-level `token`, which must therefore survive the
|
|
185
|
+
* transport-only stripping above.
|
|
186
|
+
*
|
|
187
|
+
* `exchange_oidc_token` (#2171) is one: the identity token IS the request. The blanket strip was
|
|
188
|
+
* written when no operation took a top-level `token`, and left this one reaching the server without
|
|
189
|
+
* the field it requires — so the issuer-agnostic path was unusable through the generic CLI even
|
|
190
|
+
* though direct HTTP worked. Keyed on the operation rather than dropping the strip, because the
|
|
191
|
+
* mistyped-`setup` case it guards against is real.
|
|
192
|
+
*/
|
|
193
|
+
const OPERATIONS_TAKING_A_TOKEN = new Set(['exchange_oidc_token']);
|
|
194
|
+
|
|
182
195
|
function operationFields(req: any): any {
|
|
196
|
+
const keepsToken = OPERATIONS_TAKING_A_TOKEN.has(req?.operation);
|
|
183
197
|
const fields: any = {};
|
|
184
198
|
for (const [key, value] of Object.entries(req)) {
|
|
185
|
-
if (key.startsWith('_')
|
|
199
|
+
if (key.startsWith('_')) continue;
|
|
200
|
+
if (TRANSPORT_ONLY_FIELDS.has(key) && !(key === 'token' && keepsToken)) continue;
|
|
186
201
|
fields[key] = value;
|
|
187
202
|
}
|
|
188
203
|
return fields;
|
|
@@ -764,7 +779,8 @@ export async function resolveRequestOptions(req: any): Promise<{ options: any; t
|
|
|
764
779
|
options.timeout = SSE_OPERATIONS.has(req.operation) ? SSE_OPERATION_TIMEOUT_MS : CLI_OPERATION_TIMEOUT_MS;
|
|
765
780
|
// Authentication precedence: explicitly configured credentials (dedicated args, URL
|
|
766
781
|
// userinfo, env vars) beat everything, then env-var tokens, then the saved `harper login`
|
|
767
|
-
// token,
|
|
782
|
+
// token, then a CI identity token exchanged via OIDC (#2171 — ambient, so it ranks below
|
|
783
|
+
// everything configured), and only then the legacy `username=`/`password=` fallback. The
|
|
768
784
|
// tokens must outrank that fallback: for add_user/alter_user those args are the credentials
|
|
769
785
|
// of the user being created/altered, so treating them as auth would authenticate as a user
|
|
770
786
|
// who doesn't exist yet (or as the wrong identity) instead of using the admin's session.
|
|
@@ -799,9 +815,12 @@ export async function resolveRequestOptions(req: any): Promise<{ options: any; t
|
|
|
799
815
|
const envRefreshToken = tokenPrefix ? process.env[`${tokenPrefix}_REFRESH_TOKEN`]?.trim() : undefined;
|
|
800
816
|
// A namespace that is set but blank is a broken CI secret, not a request to fall back to
|
|
801
817
|
// whatever the developer last logged in as — say so rather than switching identity silently.
|
|
802
|
-
|
|
818
|
+
const tokenNamespaceBlank = !!tokenPrefix && !envOperationToken && !envRefreshToken;
|
|
819
|
+
if (tokenNamespaceBlank) {
|
|
803
820
|
console.error(
|
|
804
|
-
`Ignoring empty ${tokenPrefix}_OPERATION_TOKEN/${tokenPrefix}_REFRESH_TOKEN; falling back to saved
|
|
821
|
+
`Ignoring empty ${tokenPrefix}_OPERATION_TOKEN/${tokenPrefix}_REFRESH_TOKEN; falling back to saved ` +
|
|
822
|
+
`login credentials. Workload identity is deliberately NOT used here: a blank token namespace is a ` +
|
|
823
|
+
`failed secret, and deploying as a different identity would hide that.`
|
|
805
824
|
);
|
|
806
825
|
}
|
|
807
826
|
|
|
@@ -819,6 +838,24 @@ export async function resolveRequestOptions(req: any): Promise<{ options: any; t
|
|
|
819
838
|
if (tokens.operation_token) {
|
|
820
839
|
options.headers.Authorization = `Bearer ${tokens.operation_token}`;
|
|
821
840
|
}
|
|
841
|
+
} else if (workloadIdentityAvailable() && !tokenNamespaceBlank) {
|
|
842
|
+
// Last credential source: no configured token, but this runner can prove its identity to
|
|
843
|
+
// the cluster directly (#2171). Deliberately below the env-var and saved tokens — an
|
|
844
|
+
// explicitly configured credential should keep working exactly as it did when someone adds
|
|
845
|
+
// `id-token: write` to a workflow, rather than silently switching which identity deploys.
|
|
846
|
+
//
|
|
847
|
+
// `!tokenNamespaceBlank` extends that invariant to the half-configured case. A CI secret
|
|
848
|
+
// that failed to populate leaves the namespace set but empty; without this, such a run
|
|
849
|
+
// would quietly deploy as the OIDC policy's user instead of failing, which is the same
|
|
850
|
+
// silent identity switch in a shape that is harder to notice.
|
|
851
|
+
// Standard operation timeout, not the caller's — by this point `options.timeout` may carry
|
|
852
|
+
// the 10-minute SSE timeout for a streaming deploy_component, and the exchange is a small
|
|
853
|
+
// fast request. Without the override a stalled exchange hangs the deploy for ten minutes,
|
|
854
|
+
// on the very operation this feature exists to serve. Same reasoning, same fix as
|
|
855
|
+
// refreshExpiredOperationToken above.
|
|
856
|
+
const exchangeOptions = { ...options, timeout: CLI_OPERATION_TIMEOUT_MS };
|
|
857
|
+
const operationToken = await exchangeWorkloadIdentityForToken(exchangeOptions, target.resolvedTarget);
|
|
858
|
+
if (operationToken) options.headers.Authorization = `Bearer ${operationToken}`;
|
|
822
859
|
}
|
|
823
860
|
}
|
|
824
861
|
// Legacy fallback for operations where `username=`/`password=` genuinely ARE the caller's
|
package/bin/copyDb.ts
CHANGED
|
@@ -6,16 +6,17 @@ import {
|
|
|
6
6
|
toRocksCompression,
|
|
7
7
|
} from '../resources/databases.ts';
|
|
8
8
|
import { open, asBinary } from 'lmdb';
|
|
9
|
-
import { join } from 'path';
|
|
9
|
+
import { isAbsolute, join, relative, sep } from 'node:path';
|
|
10
10
|
import { move, remove } from 'fs-extra';
|
|
11
11
|
import { existsSync, mkdirSync } from 'node:fs';
|
|
12
|
-
import { rename } from 'node:fs/promises';
|
|
12
|
+
import { rename, writeFile } from 'node:fs/promises';
|
|
13
13
|
import { get } from '../utility/environment/environmentManager.ts';
|
|
14
14
|
import OpenEnvironmentObject from '../utility/lmdb/OpenEnvironmentObject.ts';
|
|
15
15
|
import { OpenDBIObject } from '../utility/lmdb/OpenDBIObject.ts';
|
|
16
16
|
import { INTERNAL_DBIS_NAME, AUDIT_STORE_NAME } from '../utility/lmdb/terms.ts';
|
|
17
17
|
import { CONFIG_PARAMS, DATABASES_DIR_NAME, MIGRATING_DIR_SUFFIX } from '../utility/hdbTerms.ts';
|
|
18
|
-
import { AUDIT_STORE_OPTIONS } from '../resources/auditStore.ts';
|
|
18
|
+
import { AUDIT_STORE_OPTIONS, auditRetention } from '../resources/auditStore.ts';
|
|
19
|
+
import { blobsReadmeContent, copyBlobRootsByIndex } from '../dataLayer/blobBackup.ts';
|
|
19
20
|
import { describeSchema } from '../dataLayer/schemaDescribe.ts';
|
|
20
21
|
import { updateConfigValue } from '../config/configUtils.ts';
|
|
21
22
|
import * as hdbLogger from '../utility/logging/harper_logger.ts';
|
|
@@ -26,6 +27,7 @@ import {
|
|
|
26
27
|
beginPendingMigrationBlobSaves,
|
|
27
28
|
encodeBlobsWithFilePath,
|
|
28
29
|
endPendingMigrationBlobSaves,
|
|
30
|
+
getBlobPathsForDatabaseName,
|
|
29
31
|
} from '../resources/blob.ts';
|
|
30
32
|
import {
|
|
31
33
|
RecordEncoder,
|
|
@@ -50,18 +52,35 @@ export async function compactOnStart() {
|
|
|
50
52
|
for (const databaseName in databases) {
|
|
51
53
|
if (databaseName === 'system') continue;
|
|
52
54
|
if (databaseName.endsWith('-copy')) continue; // don't copy the copy
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
dbPath = databases[databaseName][tableName].primaryStore.path;
|
|
56
|
-
break;
|
|
57
|
-
}
|
|
58
|
-
if (!dbPath) {
|
|
55
|
+
const rootStores = getRootStores(databases[databaseName]);
|
|
56
|
+
if (rootStores.size === 0) {
|
|
59
57
|
console.log("Couldn't find any tables in database", databaseName);
|
|
60
58
|
continue;
|
|
61
59
|
}
|
|
60
|
+
if ([...rootStores].some((rootStore) => rootStore instanceof RocksDatabase)) {
|
|
61
|
+
console.log('Database', databaseName, 'is RocksDB, which compacts itself, skipping');
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
// Compaction replaces one environment file, and leaves the blob roots alone because the
|
|
65
|
+
// compacted copy goes back to this exact path under this database name. Tables in separate
|
|
66
|
+
// environments have no single file to replace, so compacting them would relocate tables and
|
|
67
|
+
// strand their blobs.
|
|
68
|
+
if (rootStores.size > 1) {
|
|
69
|
+
const message = `Skipping compaction of database ${databaseName}: its tables span ${rootStores.size} storage environments (table-specific paths), which compaction cannot replace as one file`;
|
|
70
|
+
hdbLogger.warn(message);
|
|
71
|
+
console.warn(message);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const dbPath = [...rootStores][0].path;
|
|
62
75
|
|
|
63
76
|
const backupDest = join(rootPath, 'backup', databaseName + '.mdb');
|
|
64
77
|
const copyDest = join(rootPath, DATABASES_DIR_NAME, databaseName + '-copy.mdb');
|
|
78
|
+
if (existsSync(copyDest)) {
|
|
79
|
+
const message = `Skipping compaction of database ${databaseName}: ${copyDest} already exists; inspect and rename or remove it, then re-enable '${CONFIG_PARAMS.STORAGE_COMPACTONSTART}' before retrying (this run already disabled it)`;
|
|
80
|
+
hdbLogger.warn(message);
|
|
81
|
+
console.warn(message);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
65
84
|
let recordCount = 0;
|
|
66
85
|
try {
|
|
67
86
|
recordCount = await getTotalDBRecordCount(databaseName);
|
|
@@ -70,21 +89,24 @@ export async function compactOnStart() {
|
|
|
70
89
|
hdbLogger.error('Error getting record count for database', databaseName, error);
|
|
71
90
|
console.error('Error getting record count for database', databaseName, error);
|
|
72
91
|
}
|
|
73
|
-
|
|
92
|
+
const compactionState = {
|
|
74
93
|
dbPath,
|
|
75
94
|
copyDest,
|
|
76
95
|
backupDest,
|
|
77
96
|
recordCount,
|
|
78
|
-
|
|
97
|
+
backedUp: false,
|
|
98
|
+
};
|
|
99
|
+
compactedDb.set(databaseName, compactionState);
|
|
79
100
|
|
|
80
|
-
await
|
|
101
|
+
await remove(copyDest + '-lock');
|
|
81
102
|
|
|
103
|
+
await copyDb(databaseName, copyDest, { blobs: 'preserve-source-roots' });
|
|
104
|
+
|
|
105
|
+
// The backup is the only rollback for the overwrite below, so a failed backup fails the
|
|
106
|
+
// compaction (leaving the source in place) instead of overwriting the only copy.
|
|
82
107
|
console.log('Backing up', databaseName, 'to', backupDest);
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
} catch (error) {
|
|
86
|
-
console.log('Error moving database', dbPath, 'to', backupDest, error);
|
|
87
|
-
}
|
|
108
|
+
await move(dbPath, backupDest, { overwrite: true });
|
|
109
|
+
compactionState.backedUp = true;
|
|
88
110
|
// Move compacted DB to back to original DB path
|
|
89
111
|
console.log('Moving copy compacted', databaseName, 'to', dbPath);
|
|
90
112
|
await move(copyDest, dbPath, { overwrite: true });
|
|
@@ -110,7 +132,12 @@ export async function compactOnStart() {
|
|
|
110
132
|
|
|
111
133
|
updateConfigValue(CONFIG_PARAMS.STORAGE_COMPACTONSTART, false);
|
|
112
134
|
|
|
113
|
-
for (const [_db, { dbPath, backupDest }] of compactedDb) {
|
|
135
|
+
for (const [_db, { dbPath, backupDest, backedUp }] of compactedDb) {
|
|
136
|
+
// Only a backup this run created is this run's source to restore. `backupDest` is a fixed
|
|
137
|
+
// path per database, so a retained backup from an earlier run can be sitting there — moving
|
|
138
|
+
// that over a database whose compaction failed before its own backup was taken would
|
|
139
|
+
// replace healthy data with a stale snapshot.
|
|
140
|
+
if (!backedUp) continue;
|
|
114
141
|
console.error('Moving backup database', backupDest, 'back to', dbPath);
|
|
115
142
|
try {
|
|
116
143
|
await move(backupDest, dbPath, { overwrite: true });
|
|
@@ -155,14 +182,133 @@ function noop() {
|
|
|
155
182
|
// if there are any attempts to write to the db, ignore them
|
|
156
183
|
}
|
|
157
184
|
|
|
158
|
-
|
|
185
|
+
function getRootStores(database): Set<any> {
|
|
186
|
+
const rootStores = new Set<any>();
|
|
187
|
+
for (const tableName in database) rootStores.add(database[tableName].primaryStore.rootStore);
|
|
188
|
+
return rootStores;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const BLOB_COPY_SUFFIX = '-blobs';
|
|
192
|
+
|
|
193
|
+
const STRUCTURES_KEY = Symbol.for('structures');
|
|
194
|
+
|
|
195
|
+
const MAX_COPY_RETRIES = 1000;
|
|
196
|
+
|
|
197
|
+
const MSGPACK_NIL = 0xc0;
|
|
198
|
+
|
|
199
|
+
function isWithin(path: string, directory: string): boolean {
|
|
200
|
+
const relativePath = relative(directory, path);
|
|
201
|
+
if (relativePath === '') return true;
|
|
202
|
+
if (isAbsolute(relativePath)) return false;
|
|
203
|
+
// Segment-aware: a child literally named e.g. `..copy.mdb-blobs` is a real child, not an escape —
|
|
204
|
+
// only a first segment of exactly `..` walks up out of `directory`.
|
|
205
|
+
return relativePath.split(sep)[0] !== '..';
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Read and write raw stored bytes through this handle: `openDB` builds a RecordEncoder from the DBI
|
|
210
|
+
* options whatever `encoding` says, and the live audit store also wraps `getRange` to yield decoded
|
|
211
|
+
* audit records, so a byte-for-byte copy needs the encoder detached.
|
|
212
|
+
*/
|
|
213
|
+
function useRawBytes(store) {
|
|
214
|
+
store.encoder = null;
|
|
215
|
+
store.decoder = null;
|
|
216
|
+
store.decoderCopies = false;
|
|
217
|
+
store.encoding = 'binary';
|
|
218
|
+
return store;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Copy a database's blob roots into `<targetDatabasePath>-blobs/<rootIndex>/…`. Blob files live
|
|
223
|
+
* outside the environment file and are addressed by database *name* against the running instance's
|
|
224
|
+
* configured roots, so a copy without them is unreadable anywhere but its own origin.
|
|
225
|
+
*/
|
|
226
|
+
async function copyDatabaseBlobs(sourceDatabase: string, targetDatabasePath: string, blobRoots: string[]) {
|
|
227
|
+
const populatedRoots = blobRoots.filter((root) => existsSync(root));
|
|
228
|
+
const missingRoots = blobRoots.filter((root) => !existsSync(root));
|
|
229
|
+
if (missingRoots.length > 0) {
|
|
230
|
+
const message =
|
|
231
|
+
`Configured blob root(s) ${missingRoots.join(', ')} of ${sourceDatabase} do not exist and will be copied as ` +
|
|
232
|
+
`empty; if this database has ever written blobs to them (rather than never having used them), this copy is missing those blobs.`;
|
|
233
|
+
hdbLogger.warn(message);
|
|
234
|
+
console.warn(message);
|
|
235
|
+
}
|
|
236
|
+
if (populatedRoots.length === 0) return;
|
|
237
|
+
const destination = targetDatabasePath + BLOB_COPY_SUFFIX;
|
|
238
|
+
await copyBlobRootsByIndex(destination, blobRoots);
|
|
239
|
+
await writeFile(join(destination, 'README.md'), blobsReadmeContent(blobRoots, { variant: 'copy' }));
|
|
240
|
+
const message =
|
|
241
|
+
`Copied ${populatedRoots.length} blob root(s) of ${sourceDatabase} to ${destination}. This copy is not ` +
|
|
242
|
+
`restorable without them: blobs are addressed by database name, so each <rootIndex> directory has to be ` +
|
|
243
|
+
`placed into the matching blob root of the database the copy is restored as (see ${join(destination, 'README.md')})`;
|
|
244
|
+
hdbLogger.notify(message);
|
|
245
|
+
console.log(message);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Copy a database's LMDB environment to `targetDatabasePath`.
|
|
250
|
+
*
|
|
251
|
+
* `blobs` declares what happens to the database's file-backed blobs, and is required because both
|
|
252
|
+
* answers are silently destructive when wrong: `'copy'` writes them beside the target (what an
|
|
253
|
+
* operator copying a database elsewhere needs), `'preserve-source-roots'` leaves them untouched and
|
|
254
|
+
* is only sound when the copy replaces the source environment under the same database name, which is
|
|
255
|
+
* what makes the existing roots keep resolving.
|
|
256
|
+
*/
|
|
257
|
+
export async function copyDb(
|
|
258
|
+
sourceDatabase: string,
|
|
259
|
+
targetDatabasePath: string,
|
|
260
|
+
options: { blobs: 'copy' | 'preserve-source-roots' }
|
|
261
|
+
) {
|
|
262
|
+
const blobDisposition = options?.blobs;
|
|
263
|
+
if (blobDisposition !== 'copy' && blobDisposition !== 'preserve-source-roots')
|
|
264
|
+
throw new Error(
|
|
265
|
+
`copyDb requires a blob disposition: { blobs: 'copy' } to copy ${sourceDatabase}'s blob files beside the target, ` +
|
|
266
|
+
`or { blobs: 'preserve-source-roots' } when the copy replaces the source environment in place`
|
|
267
|
+
);
|
|
159
268
|
console.log(`Copying database ${sourceDatabase} to ${targetDatabasePath}`);
|
|
160
269
|
const sourceDb = getDatabases()[sourceDatabase];
|
|
161
270
|
if (!sourceDb) throw new Error(`Source database not found: ${sourceDatabase}`);
|
|
162
|
-
|
|
271
|
+
const rootStores = getRootStores(sourceDb);
|
|
272
|
+
if (rootStores.size === 0) throw new Error(`Source database does not have any tables: ${sourceDatabase}`);
|
|
273
|
+
if (rootStores.size > 1)
|
|
274
|
+
throw new Error(
|
|
275
|
+
`Database ${sourceDatabase} spans ${rootStores.size} storage environments (table-specific paths); ` +
|
|
276
|
+
`copying it into the single environment ${targetDatabasePath} would relocate tables and strand their blobs`
|
|
277
|
+
);
|
|
278
|
+
const [rootStore] = rootStores;
|
|
279
|
+
if (rootStore instanceof RocksDatabase)
|
|
280
|
+
throw new Error(`Database ${sourceDatabase} is stored in RocksDB; copyDb copies LMDB environments only`);
|
|
281
|
+
if (existsSync(targetDatabasePath))
|
|
282
|
+
throw new Error(
|
|
283
|
+
`Copy target ${targetDatabasePath} already exists; remove it first — opening it would merge this copy into whatever it holds`
|
|
284
|
+
);
|
|
285
|
+
const blobRoots = blobDisposition === 'copy' ? getBlobPathsForDatabaseName(sourceDatabase) : [];
|
|
286
|
+
const blobDestination = targetDatabasePath + BLOB_COPY_SUFFIX;
|
|
287
|
+
if (blobDisposition === 'copy') {
|
|
288
|
+
if (existsSync(blobDestination))
|
|
289
|
+
throw new Error(`Blob copy target ${blobDestination} already exists; remove it first`);
|
|
290
|
+
// Every path a failure can remove or write through, not just the final blob destination — a
|
|
291
|
+
// staging or lock sibling landing inside a blob root would be just as destructive on cleanup.
|
|
292
|
+
const destinationPaths = [
|
|
293
|
+
targetDatabasePath,
|
|
294
|
+
targetDatabasePath + '-lock',
|
|
295
|
+
blobDestination,
|
|
296
|
+
blobDestination + '.tmp',
|
|
297
|
+
];
|
|
298
|
+
for (const root of blobRoots) {
|
|
299
|
+
for (const destinationPath of destinationPaths) {
|
|
300
|
+
if (isWithin(destinationPath, root) || isWithin(root, destinationPath))
|
|
301
|
+
throw new Error(
|
|
302
|
+
`Copy target ${targetDatabasePath} overlaps the source blob root ${root}; choose a target outside it`
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
// Suppress source writes only once the copy is going ahead: a caller that catches a rejection above
|
|
308
|
+
// keeps using these stores.
|
|
309
|
+
const primaryStoresByDbi = new Map<string, any>();
|
|
163
310
|
for (const tableName in sourceDb) {
|
|
164
311
|
const table = sourceDb[tableName];
|
|
165
|
-
// ensure that writes aren't occurring
|
|
166
312
|
table.primaryStore.put = noop;
|
|
167
313
|
table.primaryStore.remove = noop;
|
|
168
314
|
for (const attributeName in table.indices) {
|
|
@@ -174,9 +320,27 @@ export async function copyDb(sourceDatabase: string, targetDatabasePath: string)
|
|
|
174
320
|
table.auditStore.put = noop;
|
|
175
321
|
table.auditStore.remove = noop;
|
|
176
322
|
}
|
|
177
|
-
|
|
323
|
+
primaryStoresByDbi.set(table.primaryStore.name, table.primaryStore);
|
|
324
|
+
}
|
|
325
|
+
try {
|
|
326
|
+
await copyDbEnvironment(sourceDatabase, targetDatabasePath, rootStore, primaryStoresByDbi);
|
|
327
|
+
if (blobDisposition === 'copy') await copyDatabaseBlobs(sourceDatabase, targetDatabasePath, blobRoots);
|
|
328
|
+
} catch (error) {
|
|
329
|
+
// Every path removed here was created by this call — both targets are rejected above if they
|
|
330
|
+
// already exist — and a partial copy left behind is a copy someone can restore from.
|
|
331
|
+
await remove(targetDatabasePath).catch(() => {});
|
|
332
|
+
await remove(targetDatabasePath + '-lock').catch(() => {});
|
|
333
|
+
if (blobDisposition === 'copy') await remove(blobDestination).catch(() => {});
|
|
334
|
+
throw error;
|
|
178
335
|
}
|
|
179
|
-
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
async function copyDbEnvironment(
|
|
339
|
+
sourceDatabase: string,
|
|
340
|
+
targetDatabasePath: string,
|
|
341
|
+
rootStore,
|
|
342
|
+
primaryStoresByDbi: Map<string, any>
|
|
343
|
+
) {
|
|
180
344
|
// this contains the list of all the dbis
|
|
181
345
|
const sourceDbisDb = rootStore.dbisDb;
|
|
182
346
|
const sourceAuditStore = rootStore.auditStore;
|
|
@@ -184,6 +348,8 @@ export async function copyDb(sourceDatabase: string, targetDatabasePath: string)
|
|
|
184
348
|
const targetDbisDb = targetEnv.openDB({ name: INTERNAL_DBIS_NAME });
|
|
185
349
|
let written;
|
|
186
350
|
let outstandingWrites = 0;
|
|
351
|
+
// One cutoff for the whole copy so a long copy classifies every tombstone against the same instant
|
|
352
|
+
const tombstoneCutoff = Date.now() - auditRetention;
|
|
187
353
|
// we use a single transaction to get a snapshot, also we can't use snapshot: false on dupsort dbs
|
|
188
354
|
const transaction = sourceDbisDb.useReadTransaction();
|
|
189
355
|
try {
|
|
@@ -209,36 +375,83 @@ export async function copyDb(sourceDatabase: string, targetDatabasePath: string)
|
|
|
209
375
|
dbiInit.encoding = 'binary';
|
|
210
376
|
dbiInit.compression = existingCompression;
|
|
211
377
|
//dbiInit.keyEncoding = 'binary';
|
|
212
|
-
const sourceDbi = rootStore.openDB(key, dbiInit);
|
|
213
|
-
sourceDbi.decoder = null;
|
|
214
|
-
sourceDbi.decoderCopies = false;
|
|
215
|
-
sourceDbi.encoding = 'binary';
|
|
378
|
+
const sourceDbi = useRawBytes(rootStore.openDB(key, dbiInit));
|
|
216
379
|
dbiInit.compression = newCompression;
|
|
217
|
-
const targetDbi = (targetEnv as any).openDB(key, dbiInit);
|
|
218
|
-
(targetDbi as any).encoder = null;
|
|
380
|
+
const targetDbi = useRawBytes((targetEnv as any).openDB(key, dbiInit));
|
|
219
381
|
console.log('copying', key, 'from', sourceDatabase, 'to', targetDatabasePath);
|
|
220
|
-
await copyDbi(sourceDbi, targetDbi, isPrimary, transaction);
|
|
382
|
+
await copyDbi(sourceDbi, targetDbi, isPrimary, transaction, primaryStoresByDbi.get(key));
|
|
383
|
+
if (isPrimary) await verifyStructuresCopied(sourceDbi, targetDbi, key);
|
|
221
384
|
}
|
|
222
385
|
if (sourceAuditStore) {
|
|
223
|
-
|
|
386
|
+
// Each handle belongs to its own environment: a "target" handle opened on the source env
|
|
387
|
+
// writes the audit log back into the source and leaves the copy without one.
|
|
388
|
+
const sourceAuditDbi = rootStore.openDB(AUDIT_STORE_NAME, { create: false, ...AUDIT_STORE_OPTIONS });
|
|
389
|
+
if (!sourceAuditDbi) throw new Error(`Could not open the audit store of ${sourceDatabase} to copy it`);
|
|
390
|
+
const targetAuditStore = (targetEnv as any).openDB(AUDIT_STORE_NAME, AUDIT_STORE_OPTIONS);
|
|
224
391
|
console.log('copying audit log for', sourceDatabase, 'to', targetDatabasePath);
|
|
225
|
-
copyDbi(
|
|
392
|
+
await copyDbi(useRawBytes(sourceAuditDbi), useRawBytes(targetAuditStore), false, transaction);
|
|
226
393
|
}
|
|
227
394
|
|
|
228
|
-
|
|
395
|
+
/**
|
|
396
|
+
* A primary DBI's shared-structures dictionary is the whole table's decodability: without it
|
|
397
|
+
* every copied record decodes to null. It rides through the copy as a symbol-keyed entry, so
|
|
398
|
+
* confirm it landed rather than trusting the walk.
|
|
399
|
+
*/
|
|
400
|
+
async function verifyStructuresCopied(sourceDbi, targetDbi, dbiName) {
|
|
401
|
+
const sourceStructures = sourceDbi.getBinary?.(STRUCTURES_KEY);
|
|
402
|
+
if (!sourceStructures) return;
|
|
403
|
+
await written;
|
|
404
|
+
const copiedStructures = targetDbi.getBinary(STRUCTURES_KEY);
|
|
405
|
+
if (!copiedStructures || !Buffer.from(copiedStructures).equals(Buffer.from(sourceStructures)))
|
|
406
|
+
throw new Error(
|
|
407
|
+
`Copy of ${sourceDatabase}/${dbiName} to ${targetDatabasePath} lost the shared-structures dictionary ` +
|
|
408
|
+
`(${sourceStructures.length} source bytes, ${copiedStructures?.length ?? 0} copied) — every record in the copy would decode as null`
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Return a delete tombstone's local retention timestamp, decided by decoding it with the live table's
|
|
414
|
+
* record decoder. Length cannot decide it — a small shared-structures dictionary and a small
|
|
415
|
+
* record both land in a tombstone's usual size range — and `decode` returning null is not
|
|
416
|
+
* sufficient either, since it also returns null for a record whose shared structure is missing
|
|
417
|
+
* on this node. Only a metadata-bearing decode proves a tombstone; anything unprovable is kept.
|
|
418
|
+
*/
|
|
419
|
+
function getDeletedRecordTime(value, primaryStore, version) {
|
|
420
|
+
if (!primaryStore?.decoder) return;
|
|
421
|
+
try {
|
|
422
|
+
if (primaryStore.decoder.decode(value) === null && lastMetadata?.value === null)
|
|
423
|
+
return lastMetadata.localTime ?? version;
|
|
424
|
+
} catch {
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
async function copyDbi(sourceDbi, targetDbi, isPrimary, transaction, primaryStore?) {
|
|
229
430
|
let recordsCopied = 0;
|
|
230
431
|
let bytesCopied = 0;
|
|
231
432
|
let skippedRecord = 0;
|
|
232
|
-
let
|
|
433
|
+
let failedRecords = 0;
|
|
434
|
+
let retries = MAX_COPY_RETRIES;
|
|
233
435
|
let start = null;
|
|
234
|
-
|
|
436
|
+
let completed = false;
|
|
437
|
+
while (!completed && retries-- > 0) {
|
|
235
438
|
try {
|
|
236
|
-
|
|
439
|
+
// getRange, not getKeys + getEntry: on a dupSort index the latter yields one entry per
|
|
440
|
+
// unique key, dropping every duplicate
|
|
441
|
+
for (const { key, value, version } of sourceDbi.getRange(
|
|
442
|
+
isPrimary ? { start, transaction, versions: true } : { start, transaction }
|
|
443
|
+
)) {
|
|
237
444
|
try {
|
|
238
445
|
start = key;
|
|
239
|
-
|
|
240
|
-
//
|
|
241
|
-
|
|
446
|
+
// Drop a tombstone only once it is past audit retention, the point the runtime
|
|
447
|
+
// removes it too: dropping a live one loses the delete, letting a peer that
|
|
448
|
+
// missed it resurrect the record. A tombstone's body is a lone msgpack nil, so
|
|
449
|
+
// the trailing byte keeps the decode off every other record.
|
|
450
|
+
const deletedRecordTime =
|
|
451
|
+
isPrimary && typeof key !== 'symbol' && value?.[value.length - 1] === MSGPACK_NIL
|
|
452
|
+
? getDeletedRecordTime(value, primaryStore, version)
|
|
453
|
+
: undefined;
|
|
454
|
+
if (deletedRecordTime != null && deletedRecordTime < tombstoneCutoff) {
|
|
242
455
|
skippedRecord++;
|
|
243
456
|
continue;
|
|
244
457
|
}
|
|
@@ -260,6 +473,7 @@ export async function copyDb(sourceDatabase: string, targetDatabasePath: string)
|
|
|
260
473
|
outstandingWrites = 0;
|
|
261
474
|
}
|
|
262
475
|
} catch (error) {
|
|
476
|
+
failedRecords++;
|
|
263
477
|
console.error(
|
|
264
478
|
'Error copying record',
|
|
265
479
|
typeof key === 'symbol' ? 'symbol' : key,
|
|
@@ -269,36 +483,46 @@ export async function copyDb(sourceDatabase: string, targetDatabasePath: string)
|
|
|
269
483
|
targetDatabasePath,
|
|
270
484
|
error
|
|
271
485
|
);
|
|
486
|
+
break;
|
|
272
487
|
}
|
|
273
488
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
489
|
+
completed = true;
|
|
490
|
+
} catch (error) {
|
|
491
|
+
// Resume from the last key read, never past it: re-copying that key is idempotent (an
|
|
492
|
+
// identical put, and an identical dupSort pair, is a no-op) while advancing the key
|
|
493
|
+
// would jump the copy over everything in between and still reach the success path.
|
|
494
|
+
console.error(
|
|
495
|
+
`Error iterating ${sourceDatabase} near key ${typeof start === 'symbol' ? 'symbol' : JSON.stringify(start)}, retrying (${retries} retries left):`,
|
|
496
|
+
error
|
|
282
497
|
);
|
|
283
|
-
return;
|
|
284
|
-
} catch {
|
|
285
|
-
// try to resume with a bigger key
|
|
286
|
-
if (typeof start === 'string') {
|
|
287
|
-
if (start === 'z') {
|
|
288
|
-
return console.error('Reached end of dbi', start, 'for', sourceDatabase, 'to', targetDatabasePath);
|
|
289
|
-
}
|
|
290
|
-
start = start.slice(0, -2) + 'z';
|
|
291
|
-
} else if (typeof start === 'number') start++;
|
|
292
|
-
else return console.error('Unknown key type', start, 'for', sourceDatabase, 'to', targetDatabasePath);
|
|
293
498
|
}
|
|
294
499
|
}
|
|
500
|
+
// A copy that lost entries, or stopped part-way through a DBI, must not report success
|
|
501
|
+
if (!completed)
|
|
502
|
+
throw new Error(
|
|
503
|
+
`Copy of ${sourceDatabase} to ${targetDatabasePath} could not get past key ` +
|
|
504
|
+
`${typeof start === 'symbol' ? 'symbol' : JSON.stringify(start)} in ${MAX_COPY_RETRIES} attempts`
|
|
505
|
+
);
|
|
506
|
+
if (failedRecords > 0)
|
|
507
|
+
throw new Error(
|
|
508
|
+
`Copy of ${sourceDatabase} to ${targetDatabasePath} failed on ${failedRecords} entry/entries after copying ${recordsCopied}`
|
|
509
|
+
);
|
|
510
|
+
console.log(
|
|
511
|
+
'finish copying, copied',
|
|
512
|
+
recordsCopied,
|
|
513
|
+
'entries, skipped',
|
|
514
|
+
skippedRecord,
|
|
515
|
+
'delete records,',
|
|
516
|
+
bytesCopied,
|
|
517
|
+
'bytes'
|
|
518
|
+
);
|
|
295
519
|
}
|
|
296
520
|
|
|
297
521
|
await written;
|
|
298
522
|
console.log('copied database ' + sourceDatabase + ' to ' + targetDatabasePath);
|
|
299
523
|
} finally {
|
|
300
524
|
transaction.done();
|
|
301
|
-
targetEnv.close();
|
|
525
|
+
await targetEnv.close();
|
|
302
526
|
}
|
|
303
527
|
}
|
|
304
528
|
|
|
@@ -561,7 +785,6 @@ export async function copyDbToRocks(sourceRootStore, sourceDatabase: string, tar
|
|
|
561
785
|
});
|
|
562
786
|
targetHandles.push(targetDbisDb);
|
|
563
787
|
|
|
564
|
-
const STRUCTURES_KEY = Symbol.for('structures');
|
|
565
788
|
const copyStructures = (sourceDbi, storeName: string, extraTarget?: RocksDatabase) => {
|
|
566
789
|
const buffer = sourceDbi.getBinary?.(STRUCTURES_KEY);
|
|
567
790
|
if (buffer) {
|