@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
|
@@ -132,16 +132,66 @@ export function shouldAbortSlowReplay(totalElapsedMs: number, timeLimitMs = REPL
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
/**
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
135
|
+
* A corrupt transaction-log frame from rocksdb-js. `resyncPosition` is set only when intact entries
|
|
136
|
+
* follow the break, which is what distinguishes lost entries from a merely truncated tail; its
|
|
137
|
+
* absence is also all that any rocksdb-js predating that field can report.
|
|
138
|
+
*/
|
|
139
|
+
export type CorruptFrameError = RangeError & {
|
|
140
|
+
logId?: number | null;
|
|
141
|
+
position?: number | null;
|
|
142
|
+
resyncPosition?: number | null;
|
|
143
|
+
unreadableBytes?: number | null;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Corrupt frames hit by one `getRange` call, shared by its per-log iterators.
|
|
148
|
+
*
|
|
149
|
+
* `truncatedVersions` is what a consumer has to act on: a break destroys the framing after the last
|
|
150
|
+
* entry the broken log yielded, and whether the entries it swallowed continued that entry's version
|
|
151
|
+
* is exactly what can no longer be read — UNLESS that last entry's own `endTxn` already closed its
|
|
152
|
+
* transaction, in which case nothing of it was left open to swallow. That version's transaction is
|
|
153
|
+
* therefore incomplete only when it wasn't already known-closed, and replay must discard it rather
|
|
154
|
+
* than commit the part of it that was still readable. A log that broke before yielding anything
|
|
155
|
+
* truncates no transaction.
|
|
156
|
+
*
|
|
157
|
+
* `midLogBreak` is coarser: true once any break in this range left intact entries unreadable behind
|
|
158
|
+
* it (see {@link isMidLogBreak}), regardless of which version they belonged to. A consumer that must
|
|
159
|
+
* never serve a range with lost entries — an elected branch replay publishing itself as a trustworthy
|
|
160
|
+
* point-in-time copy — rejects on this rather than on `truncatedVersions`, since a mid-log break can
|
|
161
|
+
* strand entries whose version this range never even attributes to one log (harper#2016, #2063).
|
|
162
|
+
*/
|
|
163
|
+
export interface CorruptFrameStop {
|
|
164
|
+
breaks: number;
|
|
165
|
+
truncatedVersions: Set<number>;
|
|
166
|
+
midLogBreak: boolean;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Whether a corrupt frame is a mid-log break — intact entries followed it, so entries were lost
|
|
171
|
+
* rather than the log merely being torn at its tail. Shared by the reporter below and by
|
|
172
|
+
* `RocksTransactionLogStore.getRange`'s `CorruptFrameStop.midLogBreak`, so the two can't drift on
|
|
173
|
+
* what counts as a mid-log break.
|
|
174
|
+
*/
|
|
175
|
+
export function isMidLogBreak(error: CorruptFrameError): boolean {
|
|
176
|
+
return error.resyncPosition != null;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Wraps a transaction-log query iterator so a corrupt/torn frame ends that log's iteration cleanly
|
|
181
|
+
* instead of escaping as an uncaughtException.
|
|
182
|
+
*
|
|
183
|
+
* Iteration stops at the break whether or not intact entries follow it. Resuming past a mid-log
|
|
184
|
+
* break would recover those entries, but a transaction log carries no frame-level transaction
|
|
185
|
+
* boundaries: replay groups equal-version entries into one source transaction, so skipping a frame
|
|
186
|
+
* inside such a group applies and checkpoints the surviving subset of a transaction that never
|
|
187
|
+
* committed that way at the source. Availability loss is visible and recoverable; a silently torn
|
|
188
|
+
* transaction is neither. Recovery is deferred until the engine can resume at a proven boundary
|
|
189
|
+
* (harper#2016, harper#2063); `resyncPosition` is used only to report the break as lost entries
|
|
190
|
+
* rather than as a truncated tail.
|
|
141
191
|
*/
|
|
142
192
|
export function endIteratorOnCorruptFrame<T>(
|
|
143
193
|
iterator: Iterator<T>,
|
|
144
|
-
onCorruptFrame: (error:
|
|
194
|
+
onCorruptFrame: (error: CorruptFrameError) => void
|
|
145
195
|
): IterableIterator<T> {
|
|
146
196
|
let stopped = false;
|
|
147
197
|
return {
|
|
@@ -157,7 +207,7 @@ export function endIteratorOnCorruptFrame<T>(
|
|
|
157
207
|
// version-dependent (1.4.2 added hex offsets). Anything else re-throws.
|
|
158
208
|
if (!(error instanceof RangeError)) throw error;
|
|
159
209
|
stopped = true;
|
|
160
|
-
onCorruptFrame(error);
|
|
210
|
+
onCorruptFrame(error as CorruptFrameError);
|
|
161
211
|
return { done: true, value: undefined };
|
|
162
212
|
}
|
|
163
213
|
},
|
|
@@ -175,3 +225,116 @@ export function endIteratorOnCorruptFrame<T>(
|
|
|
175
225
|
},
|
|
176
226
|
};
|
|
177
227
|
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* A corrupt frame, accumulated for the life of the process. The same frame is re-encountered by
|
|
231
|
+
* every reader until each consumer's resume cursor has passed it, so this is deduplicated by
|
|
232
|
+
* location and the repeats become a count.
|
|
233
|
+
*/
|
|
234
|
+
export interface CorruptFrameReport {
|
|
235
|
+
log: string;
|
|
236
|
+
logId?: number;
|
|
237
|
+
position?: number;
|
|
238
|
+
/** Intact entries followed the break, so entries were lost rather than merely truncated. */
|
|
239
|
+
midLog: boolean;
|
|
240
|
+
/** Extent of the unreadable region, when the engine reports it; 0 when nothing valid follows it. */
|
|
241
|
+
unreadableBytes: number;
|
|
242
|
+
firstSeen: number;
|
|
243
|
+
lastSeen: number;
|
|
244
|
+
occurrences: number;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/** Distinct break sites retained. One physical corruption yields one site, so this is generous. */
|
|
248
|
+
export const MAX_CORRUPT_FRAME_REPORTS = 256;
|
|
249
|
+
|
|
250
|
+
// Re-encounters move a site to the end, so the first key is the least recently seen. Full means
|
|
251
|
+
// evicting that one rather than refusing a new site, which could not then be deduplicated.
|
|
252
|
+
const corruptFrameReports = new Map<string, CorruptFrameReport>();
|
|
253
|
+
let evictedCorruptFrameReports = 0;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Every corrupt frame seen by this worker. This is not yet consumed by cluster/health status;
|
|
257
|
+
* callers must aggregate it across worker threads before exposing a node-wide signal.
|
|
258
|
+
*
|
|
259
|
+
* Mid-log breaks are immediately logged at error level even without that consumer.
|
|
260
|
+
*/
|
|
261
|
+
export function getCorruptFrameReports(): CorruptFrameReport[] {
|
|
262
|
+
return [...corruptFrameReports.values()];
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/** Break sites evicted because {@link MAX_CORRUPT_FRAME_REPORTS} was reached. */
|
|
266
|
+
export function getEvictedCorruptFrameReportCount(): number {
|
|
267
|
+
return evictedCorruptFrameReports;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export function clearCorruptFrameReports() {
|
|
271
|
+
corruptFrameReports.clear();
|
|
272
|
+
evictedCorruptFrameReports = 0;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// `logId`/`position` are absent on any rocksdb-js predating the resync support, and every break on
|
|
276
|
+
// a stream would then collapse onto one key — folding genuinely different corruptions into a single
|
|
277
|
+
// count that only ever logs once. The message carries the offset and file in text, so it separates
|
|
278
|
+
// them when the fields can't.
|
|
279
|
+
function corruptFrameKey(logName: string, error: CorruptFrameError): string {
|
|
280
|
+
const { logId, position } = error;
|
|
281
|
+
return logId != null && position != null
|
|
282
|
+
? `${logName}\u0000${logId}:${position}`
|
|
283
|
+
: `${logName}\u0000${error.message}`;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Records a corrupt frame and logs it once per distinct break.
|
|
288
|
+
*
|
|
289
|
+
* A mid-log break is an `error`, not a `warn`: entries after it were acknowledged and are now
|
|
290
|
+
* quarantined behind it. Severity follows the break's own shape, never this pass's outcome — every
|
|
291
|
+
* pass stops, so keying on that would report the #2063 signature with the benign torn-tail `warn`.
|
|
292
|
+
* A site first seen as a torn tail can escalate later, since only a rocksdb-js that reports
|
|
293
|
+
* `resyncPosition` can tell the two apart.
|
|
294
|
+
*/
|
|
295
|
+
export function createCorruptFrameReporter(logger: {
|
|
296
|
+
warn: (message: string, error?: unknown) => void;
|
|
297
|
+
error: (message: string, error?: unknown) => void;
|
|
298
|
+
}) {
|
|
299
|
+
return (logName: string) => (error: CorruptFrameError) => {
|
|
300
|
+
const midLog = isMidLogBreak(error);
|
|
301
|
+
const unreadableBytes = error.unreadableBytes ?? 0;
|
|
302
|
+
const now = Date.now();
|
|
303
|
+
const key = corruptFrameKey(logName, error);
|
|
304
|
+
const existing = corruptFrameReports.get(key);
|
|
305
|
+
if (existing) {
|
|
306
|
+
corruptFrameReports.delete(key);
|
|
307
|
+
corruptFrameReports.set(key, existing);
|
|
308
|
+
existing.occurrences++;
|
|
309
|
+
existing.lastSeen = now;
|
|
310
|
+
if (!midLog || existing.midLog) return;
|
|
311
|
+
existing.midLog = true;
|
|
312
|
+
existing.unreadableBytes = unreadableBytes;
|
|
313
|
+
} else {
|
|
314
|
+
if (corruptFrameReports.size >= MAX_CORRUPT_FRAME_REPORTS) {
|
|
315
|
+
corruptFrameReports.delete(corruptFrameReports.keys().next().value);
|
|
316
|
+
evictedCorruptFrameReports++;
|
|
317
|
+
}
|
|
318
|
+
corruptFrameReports.set(key, {
|
|
319
|
+
log: logName,
|
|
320
|
+
logId: error.logId ?? undefined,
|
|
321
|
+
position: error.position ?? undefined,
|
|
322
|
+
midLog,
|
|
323
|
+
unreadableBytes,
|
|
324
|
+
firstSeen: now,
|
|
325
|
+
lastSeen: now,
|
|
326
|
+
occurrences: 1,
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
if (midLog) {
|
|
330
|
+
logger.error(
|
|
331
|
+
`Corrupt entry in transaction log "${logName}"; ${unreadableBytes} byte(s) are unreadable and the entries within them are lost. ` +
|
|
332
|
+
'Intact entries follow the break, but reading stops there rather than skipping the frame, which could tear a source transaction: ' +
|
|
333
|
+
'they are quarantined until the log is repaired or this node is re-cloned, and they are neither replayed nor replicated meanwhile.',
|
|
334
|
+
error
|
|
335
|
+
);
|
|
336
|
+
} else {
|
|
337
|
+
logger.warn(`Stopping transaction log "${logName}" at a corrupt entry during replay`, error);
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
}
|
package/resources/search.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { ClientError, IndexRebuildingError, Violation } from '../utility/errors/hdbError.ts';
|
|
2
2
|
import { OVERFLOW_MARKER, MAX_SEARCH_KEY_LENGTH, SEARCH_TYPES } from '../utility/lmdb/terms.ts';
|
|
3
3
|
import { compareKeys, MAXIMUM_KEY, writeKey } from 'ordered-binary';
|
|
4
|
-
import { SKIP } from '@harperfast/extended-iterable';
|
|
4
|
+
import { SKIP, ExtendedIterable } from '@harperfast/extended-iterable';
|
|
5
5
|
import { INVALIDATED, EVICTED, freezeRecord } from './Table.ts';
|
|
6
6
|
import type { DirectCondition, Id } from './ResourceInterface.ts';
|
|
7
7
|
import { RequestTarget } from './RequestTarget.ts';
|
|
8
8
|
import { lastMetadata } from './RecordEncoder.ts';
|
|
9
|
+
import { writeKeyId } from './DatabaseTransaction.ts';
|
|
9
10
|
import { recordAction } from './analytics/write';
|
|
10
11
|
import { RocksDatabase } from '@harperfast/rocksdb-js';
|
|
11
12
|
|
|
@@ -232,6 +233,41 @@ function composeRecordFilter(recordFilters, table, context): (primaryKey: Id) =>
|
|
|
232
233
|
};
|
|
233
234
|
}
|
|
234
235
|
|
|
236
|
+
/**
|
|
237
|
+
* A record's index entries are not adjacent — the composite `[indexedValue, primaryKey]` key sorts
|
|
238
|
+
* on the indexed value first — so comparing neighbours cannot collapse them and the scan has to
|
|
239
|
+
* remember what it already yielded (#2434).
|
|
240
|
+
*
|
|
241
|
+
* Heap cost is one key per distinct record in the scanned range, held for the life of the scan, and
|
|
242
|
+
* a page window does not cap it: sibling-condition and row filters run downstream, so a selective
|
|
243
|
+
* filter keeps the scan running and the set growing while the page fills. On a multi-million-row
|
|
244
|
+
* range that is hundreds of MB where main streamed at O(1). Accepted for #2434 over the bounded
|
|
245
|
+
* alternative, which costs a primary read per index entry.
|
|
246
|
+
*/
|
|
247
|
+
function distinctRecords(entries: any): AsyncIterable<Id> {
|
|
248
|
+
const distinct = new ExtendedIterable();
|
|
249
|
+
(distinct as any).iterate = (options) => {
|
|
250
|
+
// A non-scalar key decodes to a fresh instance per entry, so identity never matches it;
|
|
251
|
+
// `writeKeyId` is the store's own key equality. Its bytes get their own set because a scalar
|
|
252
|
+
// string id can legitimately carry exactly those bytes, and one set would fold the two —
|
|
253
|
+
// the collision `flattenKey` has, and the reason Table.ts prefixes its key ids.
|
|
254
|
+
const yieldedKeys = new Set();
|
|
255
|
+
const yieldedEncodedKeys = new Set();
|
|
256
|
+
// map rather than filter: filter clears `continueOnRecoverableError` for everything below it
|
|
257
|
+
return entries
|
|
258
|
+
.map((primaryKey) => {
|
|
259
|
+
const isEncoded = typeof primaryKey === 'object' && primaryKey !== null;
|
|
260
|
+
const yielded = isEncoded ? yieldedEncodedKeys : yieldedKeys;
|
|
261
|
+
const identity = isEncoded ? writeKeyId(primaryKey) : primaryKey;
|
|
262
|
+
if (yielded.has(identity)) return SKIP;
|
|
263
|
+
yielded.add(identity);
|
|
264
|
+
return primaryKey;
|
|
265
|
+
})
|
|
266
|
+
.iterate(options);
|
|
267
|
+
};
|
|
268
|
+
return distinct as any;
|
|
269
|
+
}
|
|
270
|
+
|
|
235
271
|
/**
|
|
236
272
|
* Search for records or keys, based on the search condition, using an index if available
|
|
237
273
|
* @param searchCondition
|
|
@@ -261,6 +297,9 @@ export function searchByIndex(
|
|
|
261
297
|
throw new ClientError(`Search condition for ${attribute_name} must have a value`);
|
|
262
298
|
}
|
|
263
299
|
let needFullScan;
|
|
300
|
+
// `[indexedValue, primaryKey]` is unique, so a scan that stays inside one indexed value cannot
|
|
301
|
+
// reach a record twice and skips the collapse below
|
|
302
|
+
let scansOneIndexedValue;
|
|
264
303
|
if (Array.isArray(attribute_name)) {
|
|
265
304
|
const firstAttributeName = attribute_name[0];
|
|
266
305
|
// get the potential relationship attribute
|
|
@@ -388,6 +427,7 @@ export function searchByIndex(
|
|
|
388
427
|
start = value;
|
|
389
428
|
end = value;
|
|
390
429
|
inclusiveEnd = true;
|
|
430
|
+
scansOneIndexedValue = true;
|
|
391
431
|
break;
|
|
392
432
|
case 'in':
|
|
393
433
|
// Phase 1: route through filter — index-merge optimization is a Phase 2 follow-up.
|
|
@@ -531,7 +571,7 @@ export function searchByIndex(
|
|
|
531
571
|
}
|
|
532
572
|
return loaded;
|
|
533
573
|
}
|
|
534
|
-
|
|
574
|
+
const scanned = index.getRange(rangeOptions).map(
|
|
535
575
|
filter
|
|
536
576
|
? function ({ key, value }) {
|
|
537
577
|
let recordMatcher: any;
|
|
@@ -554,6 +594,14 @@ export function searchByIndex(
|
|
|
554
594
|
}
|
|
555
595
|
: ({ value }) => value
|
|
556
596
|
);
|
|
597
|
+
// Collapsing AFTER the map is required, not incidental: the condition's own filter tests one
|
|
598
|
+
// element at a time, so a record whose first entry fails it and whose second passes must
|
|
599
|
+
// still be reached. Collapsing first would settle that record on the failing entry and drop
|
|
600
|
+
// it. Scoped to attributes the schema declares multi-valued; a runtime array under an
|
|
601
|
+
// undeclared attribute repeats the same way but stays outside this boundary.
|
|
602
|
+
return scansOneIndexedValue || !findAttribute(Table.attributes, attribute_name)?.elements
|
|
603
|
+
? scanned
|
|
604
|
+
: distinctRecords(scanned);
|
|
557
605
|
} else {
|
|
558
606
|
return Table.primaryStore
|
|
559
607
|
.getRange(reverse ? { end: true, transaction, reverse: true } : { start: true, transaction })
|
|
@@ -1112,6 +1160,91 @@ export function filterByType(searchCondition, Table, context, filtered, isPrimar
|
|
|
1112
1160
|
}
|
|
1113
1161
|
}
|
|
1114
1162
|
|
|
1163
|
+
/**
|
|
1164
|
+
* Estimates a range comparator's entry count from the store's statistical estimate, blended with
|
|
1165
|
+
* the table-fraction heuristic by the estimate's confidence so low-confidence estimates degrade
|
|
1166
|
+
* to the old behavior. Returns undefined (caller falls back to the heuristic) when the store
|
|
1167
|
+
* cannot estimate, the shape is unexpected, or the executed range wouldn't match this one.
|
|
1168
|
+
*/
|
|
1169
|
+
function estimateRangeCondition(table, condition, searchType, fraction) {
|
|
1170
|
+
const attributeName = condition[0] ?? condition.attribute;
|
|
1171
|
+
const isPrimaryKey = attributeName === table.primaryKey;
|
|
1172
|
+
const store = isPrimaryKey ? table.primaryStore : table.indices[attributeName];
|
|
1173
|
+
// LMDB-backed and custom index stores do not implement estimateCount
|
|
1174
|
+
if (typeof store?.estimateCount !== 'function') return undefined;
|
|
1175
|
+
let value = condition[1] ?? condition.value;
|
|
1176
|
+
if (value instanceof Date) value = value.getTime();
|
|
1177
|
+
let range;
|
|
1178
|
+
switch (searchType) {
|
|
1179
|
+
case 'lt':
|
|
1180
|
+
// `start: true` mirrors searchByIndex: `true` sorts above `null`, so an indexNulls
|
|
1181
|
+
// index's `[null, primaryKey]` entries are outside the executed range
|
|
1182
|
+
range = { start: true, end: value };
|
|
1183
|
+
break;
|
|
1184
|
+
case 'le':
|
|
1185
|
+
range = { start: true, end: value, inclusiveEnd: true };
|
|
1186
|
+
break;
|
|
1187
|
+
case 'gt':
|
|
1188
|
+
range = { start: value, exclusiveStart: true };
|
|
1189
|
+
break;
|
|
1190
|
+
case 'ge':
|
|
1191
|
+
range = { start: value };
|
|
1192
|
+
break;
|
|
1193
|
+
case 'between':
|
|
1194
|
+
case 'gele':
|
|
1195
|
+
case 'gelt':
|
|
1196
|
+
case 'gtlt':
|
|
1197
|
+
case 'gtle': {
|
|
1198
|
+
if (!Array.isArray(value)) return undefined;
|
|
1199
|
+
let [start, end] = value;
|
|
1200
|
+
if (start instanceof Date) start = start.getTime();
|
|
1201
|
+
if (end instanceof Date) end = end.getTime();
|
|
1202
|
+
range = {
|
|
1203
|
+
start,
|
|
1204
|
+
end,
|
|
1205
|
+
inclusiveEnd: searchType === 'between' || searchType === 'gele' || searchType === 'gtle',
|
|
1206
|
+
exclusiveStart: searchType === 'gtlt' || searchType === 'gtle',
|
|
1207
|
+
};
|
|
1208
|
+
break;
|
|
1209
|
+
}
|
|
1210
|
+
case 'starts_with': {
|
|
1211
|
+
const prefix = value?.toString();
|
|
1212
|
+
if (!prefix) return undefined;
|
|
1213
|
+
range = { start: prefix, end: getStringPrefixUpperBound(prefix) };
|
|
1214
|
+
break;
|
|
1215
|
+
}
|
|
1216
|
+
case 'prefix': {
|
|
1217
|
+
let start = Array.isArray(value) ? value : [value, null];
|
|
1218
|
+
if (start[start.length - 1] != null) start = start.concat(null);
|
|
1219
|
+
const end = start.slice(0);
|
|
1220
|
+
end[end.length - 1] = MAXIMUM_KEY;
|
|
1221
|
+
range = { start, end };
|
|
1222
|
+
break;
|
|
1223
|
+
}
|
|
1224
|
+
default:
|
|
1225
|
+
return undefined;
|
|
1226
|
+
}
|
|
1227
|
+
// Long string bounds get truncated + filtered at execution (searchByIndex), so the
|
|
1228
|
+
// executed range is wider than this one; don't estimate what won't be iterated.
|
|
1229
|
+
if (
|
|
1230
|
+
(typeof range.start === 'string' && range.start.length > MAX_SEARCH_KEY_LENGTH) ||
|
|
1231
|
+
(typeof range.end === 'string' && range.end.length > MAX_SEARCH_KEY_LENGTH)
|
|
1232
|
+
) {
|
|
1233
|
+
return undefined;
|
|
1234
|
+
}
|
|
1235
|
+
let count, confidence;
|
|
1236
|
+
try {
|
|
1237
|
+
({ count, confidence } = store.estimateCount(range) ?? {});
|
|
1238
|
+
} catch {
|
|
1239
|
+
// a concurrently closing/dropped store must degrade the plan, not fail the query
|
|
1240
|
+
return undefined;
|
|
1241
|
+
}
|
|
1242
|
+
if (!Number.isFinite(count) || count < 0 || !Number.isFinite(confidence) || confidence < 0 || confidence > 1)
|
|
1243
|
+
return undefined;
|
|
1244
|
+
const heuristic = fraction * estimatedEntryCount(table.primaryStore) + 1;
|
|
1245
|
+
return Math.max(1, Math.round(confidence * count + (1 - confidence) * heuristic));
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1115
1248
|
export function estimateCondition(table) {
|
|
1116
1249
|
function estimateConditionForTable(condition) {
|
|
1117
1250
|
if (condition.estimated_count === undefined) {
|
|
@@ -1141,7 +1274,14 @@ export function estimateCondition(table) {
|
|
|
1141
1274
|
// skip if it is cached
|
|
1142
1275
|
let searchType = condition.comparator || condition.search_type;
|
|
1143
1276
|
searchType = ALTERNATE_COMPARATOR_NAMES[searchType] || searchType;
|
|
1144
|
-
if (
|
|
1277
|
+
if (condition.negated) {
|
|
1278
|
+
// a negated condition always executes as a full scan (searchByIndex forces
|
|
1279
|
+
// needFullScan), so follow the filter-only convention used by contains/ends_with:
|
|
1280
|
+
// estimate Infinity so its positive-range estimate can never win the driving-condition
|
|
1281
|
+
// ordering. Short-circuit here rather than computing (and discarding) a positive-range
|
|
1282
|
+
// estimate that would cross the native FFI boundary for nothing.
|
|
1283
|
+
condition.estimated_count = Infinity;
|
|
1284
|
+
} else if (searchType === SEARCH_TYPES.EQUALS || !searchType) {
|
|
1145
1285
|
const attribute_name = condition[0] ?? condition.attribute;
|
|
1146
1286
|
if (attribute_name == null || attribute_name === table.primaryKey) condition.estimated_count = 1;
|
|
1147
1287
|
else if (Array.isArray(attribute_name) && attribute_name.length > 1) {
|
|
@@ -1192,11 +1332,14 @@ export function estimateCondition(table) {
|
|
|
1192
1332
|
} else if (Array.isArray(condition.value)) {
|
|
1193
1333
|
condition.estimated_count = Infinity;
|
|
1194
1334
|
} else condition.estimated_count = Infinity;
|
|
1195
|
-
// for range queries (betweens, startsWith, greater, etc.), just arbitrarily guess
|
|
1196
1335
|
} else if (searchType === 'starts_with' || searchType === 'prefix')
|
|
1197
|
-
condition.estimated_count =
|
|
1336
|
+
condition.estimated_count =
|
|
1337
|
+
estimateRangeCondition(table, condition, searchType, STARTS_WITH_ESTIMATE) ??
|
|
1338
|
+
STARTS_WITH_ESTIMATE * estimatedEntryCount(table.primaryStore) + 1;
|
|
1198
1339
|
else if (searchType === 'between')
|
|
1199
|
-
condition.estimated_count =
|
|
1340
|
+
condition.estimated_count =
|
|
1341
|
+
estimateRangeCondition(table, condition, searchType, BETWEEN_ESTIMATE) ??
|
|
1342
|
+
BETWEEN_ESTIMATE * estimatedEntryCount(table.primaryStore) + 1;
|
|
1200
1343
|
else if (searchType === 'sort') {
|
|
1201
1344
|
const attribute_name = condition[0] ?? condition.attribute;
|
|
1202
1345
|
const index = table.indices[attribute_name];
|
|
@@ -1211,7 +1354,10 @@ export function estimateCondition(table) {
|
|
|
1211
1354
|
if (index?.customIndex?.estimateCount)
|
|
1212
1355
|
// allow custom index to define its own estimation of counts
|
|
1213
1356
|
condition.estimated_count = index.customIndex.estimateCount(condition.value);
|
|
1214
|
-
else
|
|
1357
|
+
else
|
|
1358
|
+
condition.estimated_count =
|
|
1359
|
+
estimateRangeCondition(table, condition, searchType, OPEN_RANGE_ESTIMATE) ??
|
|
1360
|
+
OPEN_RANGE_ESTIMATE * estimatedEntryCount(table.primaryStore) + 1;
|
|
1215
1361
|
}
|
|
1216
1362
|
// we give a condition significantly more weight/preference if we will be ordering by it
|
|
1217
1363
|
if (typeof condition.descending === 'boolean') condition.estimated_count /= 2;
|
|
@@ -1397,6 +1543,7 @@ function parseBlock(query, expectedEnd) {
|
|
|
1397
1543
|
break;
|
|
1398
1544
|
case 'group-by':
|
|
1399
1545
|
recordError('group by is not implemented yet');
|
|
1546
|
+
break;
|
|
1400
1547
|
case 'sort':
|
|
1401
1548
|
query.sort = toSortObject(args);
|
|
1402
1549
|
break;
|
|
@@ -95,7 +95,7 @@ export function addSubscription(table, key, listener?: (key) => any, startTime?:
|
|
|
95
95
|
* subscription and get the initial state.
|
|
96
96
|
*/
|
|
97
97
|
class Subscription extends IterableEventQueue {
|
|
98
|
-
listener: (recordId: Id, auditEntry: any,
|
|
98
|
+
listener: (recordId: Id, auditEntry: any, txnLogKey: number, beginTxn: boolean) => void;
|
|
99
99
|
subscriptions: any;
|
|
100
100
|
startTime?: number;
|
|
101
101
|
includeDescendants?: boolean;
|
|
@@ -178,10 +178,10 @@ function notifyFromTransactionData(subscriptions, auditLogIterable?, allowYield
|
|
|
178
178
|
}
|
|
179
179
|
if (result.done) break;
|
|
180
180
|
const auditRecord = result.value;
|
|
181
|
-
const timestamp: number = auditRecord.
|
|
181
|
+
const timestamp: number = auditRecord.txnLogKey;
|
|
182
182
|
subscriptions.lastTxnTime = timestamp;
|
|
183
183
|
// the transaction extent: RocksDB entries committed together share the log key (record
|
|
184
|
-
// versions may differ); LMDB's
|
|
184
|
+
// versions may differ); LMDB's transaction-log key is per-entry, so version delimits there
|
|
185
185
|
const txnKey = auditStore.reusableIterable ? timestamp : auditRecord.version;
|
|
186
186
|
if (ACTIONS_OF_INTEREST.includes(auditRecord.type)) {
|
|
187
187
|
const tableSubscriptions = subscriptions[auditRecord.tableId];
|
package/security/auth.ts
CHANGED
|
@@ -7,13 +7,21 @@ import { v4 as uuid } from 'uuid';
|
|
|
7
7
|
import * as env from '../utility/environment/environmentManager.ts';
|
|
8
8
|
import { CONFIG_PARAMS, AUTH_AUDIT_STATUS, AUTH_AUDIT_TYPES } from '../utility/hdbTerms.ts';
|
|
9
9
|
import harperLogger from '../utility/logging/harper_logger.ts';
|
|
10
|
-
const { forComponent, AuthAuditLog } = harperLogger;
|
|
10
|
+
const { forComponent, AuthAuditLog, errorForLog } = harperLogger;
|
|
11
11
|
import serverHandlers from '../server/itc/serverHandlers.js';
|
|
12
12
|
const { user } = serverHandlers;
|
|
13
|
-
import { Headers, addVaryHeader } from '../server/serverHelpers/Headers.ts';
|
|
13
|
+
import { Headers, addVaryHeader, SHARED_CACHE_OPTIN, PRIVATE_SCOPE } from '../server/serverHelpers/Headers.ts';
|
|
14
14
|
import { convertToMS } from '../utility/common_utils.ts';
|
|
15
15
|
import { verifyCertificate } from './certificateVerification/index.ts';
|
|
16
|
+
import {
|
|
17
|
+
credentialRejectionError,
|
|
18
|
+
deferCredentialRejection,
|
|
19
|
+
getDeferredCredentialRejection,
|
|
20
|
+
isCredentialRejection,
|
|
21
|
+
} from './deferredAuthentication.ts';
|
|
16
22
|
import { serializeMessage } from '../server/serverHelpers/contentTypes.ts';
|
|
23
|
+
import { hdbErrors } from '../utility/errors/hdbError.ts';
|
|
24
|
+
const { AUTHENTICATION_ERROR_MSGS, HTTP_STATUS_CODES } = hdbErrors;
|
|
17
25
|
const authLogger = forComponent('authentication');
|
|
18
26
|
const { debug } = authLogger;
|
|
19
27
|
const authEventLog = authLogger.withTag('auth-event');
|
|
@@ -50,10 +58,6 @@ const LOG_AUTH_FAILED = env.get(CONFIG_PARAMS.LOGGING_AUDITAUTHEVENTS_LOGFAILED)
|
|
|
50
58
|
|
|
51
59
|
const DEFAULT_COOKIE_EXPIRES = 'Tue, 01 Oct 8307 19:33:20 GMT';
|
|
52
60
|
|
|
53
|
-
// RFC 9111 cache-scope directives; boundaries on both sides so a token like `public-foo` doesn't match
|
|
54
|
-
const SHARED_CACHE_OPTIN = /(^|[,\s])(public|s-maxage)($|[\s,;=])/i;
|
|
55
|
-
const PRIVATE_SCOPE = /(^|[,\s])(private|no-store)($|[\s,;=])/i;
|
|
56
|
-
|
|
57
61
|
let authorizationCache = new Map();
|
|
58
62
|
server.onInvalidatedUser(() => {
|
|
59
63
|
// TODO: Eventually we probably want to be able to invalidate individual users
|
|
@@ -190,7 +194,13 @@ export async function authentication(request, nextHandler) {
|
|
|
190
194
|
if (request.user) {
|
|
191
195
|
// already authenticated
|
|
192
196
|
} else if (authorization) {
|
|
193
|
-
|
|
197
|
+
let cachedUser = authorizationCache.get(authorization);
|
|
198
|
+
// A cached Bearer identity must not outlive its token: expiry is the only revocation
|
|
199
|
+
// mechanism for scoped tokens, so it has to be exact, not cache-TTL-fuzzy.
|
|
200
|
+
if (cachedUser?.authExpiresAt && cachedUser.authExpiresAt * 1000 <= Date.now()) {
|
|
201
|
+
authorizationCache.delete(authorization);
|
|
202
|
+
cachedUser = undefined;
|
|
203
|
+
}
|
|
194
204
|
if (cachedUser?.role) {
|
|
195
205
|
// Shallow-clone so verifyPerms's `role.permission = fullRolePerms` reassignment
|
|
196
206
|
// doesn't mutate the cache entry (defense-in-depth; operations and other
|
|
@@ -204,6 +214,7 @@ export async function authentication(request, nextHandler) {
|
|
|
204
214
|
const strategy = authorization.slice(0, spaceIndex);
|
|
205
215
|
const credentials = authorization.slice(spaceIndex + 1);
|
|
206
216
|
let username, password;
|
|
217
|
+
let credentialRejection;
|
|
207
218
|
try {
|
|
208
219
|
switch (strategy) {
|
|
209
220
|
case 'Basic':
|
|
@@ -231,12 +242,23 @@ export async function authentication(request, nextHandler) {
|
|
|
231
242
|
// API has its own logic for handling this
|
|
232
243
|
status: -1,
|
|
233
244
|
});
|
|
234
|
-
} catch {
|
|
245
|
+
} catch (refreshError) {
|
|
246
|
+
// Preserve refresh-validation faults; only a tagged rejection permits falling
|
|
247
|
+
// back to the original operation-token rejection.
|
|
248
|
+
if (!isCredentialRejection(refreshError)) throw refreshError;
|
|
235
249
|
throw error;
|
|
236
250
|
}
|
|
237
251
|
}
|
|
252
|
+
// A non-'invalid token' rejection (e.g. expired) must propagate, not fall
|
|
253
|
+
// through to caching an undefined user (which would read as anonymous).
|
|
254
|
+
throw error;
|
|
238
255
|
}
|
|
239
256
|
break;
|
|
257
|
+
default:
|
|
258
|
+
throw credentialRejectionError(
|
|
259
|
+
AUTHENTICATION_ERROR_MSGS.GENERIC_AUTH_FAIL,
|
|
260
|
+
HTTP_STATUS_CODES.UNAUTHORIZED
|
|
261
|
+
);
|
|
240
262
|
}
|
|
241
263
|
} catch (err) {
|
|
242
264
|
if (LOG_AUTH_FAILED) {
|
|
@@ -247,18 +269,31 @@ export async function authentication(request, nextHandler) {
|
|
|
247
269
|
}
|
|
248
270
|
}
|
|
249
271
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
272
|
+
const internalFault = !isCredentialRejection(err);
|
|
273
|
+
if (request.isOperationsServer || internalFault) {
|
|
274
|
+
if (internalFault) authLogger.error('Authentication failed internally', errorForLog(err));
|
|
275
|
+
return applyResponseHeaders({
|
|
276
|
+
status: 401,
|
|
277
|
+
body: serializeMessage(
|
|
278
|
+
{ error: internalFault ? AUTHENTICATION_ERROR_MSGS.GENERIC_AUTH_FAIL : err.message },
|
|
279
|
+
request
|
|
280
|
+
),
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
credentialRejection = err;
|
|
254
284
|
}
|
|
255
285
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
286
|
+
if (credentialRejection) {
|
|
287
|
+
deferCredentialRejection(request, credentialRejection, strategy);
|
|
288
|
+
} else {
|
|
289
|
+
authorizationCache.set(authorization, newUser);
|
|
290
|
+
if (LOG_AUTH_SUCCESSFUL && newUser != null)
|
|
291
|
+
authAuditLog(newUser.username, AUTH_AUDIT_STATUS.SUCCESS, strategy);
|
|
292
|
+
// Shallow-clone so verifyPerms's `role.permission = fullRolePerms` reassignment
|
|
293
|
+
// doesn't mutate the just-stored cache entry (defense-in-depth).
|
|
294
|
+
if (newUser?.role) {
|
|
295
|
+
newUser = { ...newUser, role: { ...newUser.role, permission: { ...newUser.role.permission } } };
|
|
296
|
+
}
|
|
262
297
|
}
|
|
263
298
|
}
|
|
264
299
|
|
|
@@ -346,16 +381,19 @@ export async function authentication(request, nextHandler) {
|
|
|
346
381
|
if (!response) return response;
|
|
347
382
|
if (response.status === 401) {
|
|
348
383
|
wasUnauthorized = true;
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
384
|
+
// Downstream owns the challenge or redirect after Harper deferred the credential decision.
|
|
385
|
+
if (!getDeferredCredentialRejection(request)) {
|
|
386
|
+
if (
|
|
387
|
+
headers['user-agent']?.startsWith('Mozilla') &&
|
|
388
|
+
headers.accept?.startsWith('text/html') &&
|
|
389
|
+
resources.loginPath
|
|
390
|
+
) {
|
|
391
|
+
// on the web if we have a login page, default to redirecting to it
|
|
392
|
+
response.status = 302;
|
|
393
|
+
response.headers.set('Location', resources.loginPath(request));
|
|
394
|
+
} // the HTTP specified way of indicating HTTP authentication methods supported:
|
|
395
|
+
else response.headers.set('WWW-Authenticate', 'Basic');
|
|
396
|
+
}
|
|
359
397
|
}
|
|
360
398
|
return applyResponseHeaders(response);
|
|
361
399
|
} catch (error) {
|
|
@@ -367,7 +405,8 @@ export async function authentication(request, nextHandler) {
|
|
|
367
405
|
// if we are rejecting the credentials (401, possibly rewritten to a login redirect); such a
|
|
368
406
|
// response must never be stored by a shared cache and served to a different principal (#1565)
|
|
369
407
|
const rejectedAuth = response?.status === 401 || wasUnauthorized;
|
|
370
|
-
|
|
408
|
+
// A downstream response produced under the untouched credential remains identity-dependent (#1565).
|
|
409
|
+
const identityDependent = !!request.user || rejectedAuth || !!getDeferredCredentialRejection(request);
|
|
371
410
|
// with CORS enabled the response is origin-dependent — ACAO reflects the request Origin, and
|
|
372
411
|
// its absence when no Origin was sent is origin-dependent too — so a shared cache must
|
|
373
412
|
// partition on Origin either way (#1518)
|