kuzzle 2.56.0 → 2.57.0-beta.2
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/dist/bin/copy-binaries.js +71 -4
- package/dist/bin/start-kuzzle-server +191 -97
- package/dist/index.d.ts +31 -1
- package/dist/index.js +45 -2
- package/dist/lib/api/controllers/adminController.d.ts +4 -3
- package/dist/lib/api/controllers/adminController.js +1 -2
- package/dist/lib/api/controllers/authController.d.ts +37 -16
- package/dist/lib/api/controllers/authController.js +88 -39
- package/dist/lib/api/controllers/baseController.d.ts +10 -5
- package/dist/lib/api/controllers/baseController.js +36 -15
- package/dist/lib/api/controllers/bulkController.d.ts +11 -7
- package/dist/lib/api/controllers/bulkController.js +28 -5
- package/dist/lib/api/controllers/clusterController.d.ts +2 -2
- package/dist/lib/api/controllers/clusterController.js +3 -3
- package/dist/lib/api/controllers/collectionController.d.ts +57 -21
- package/dist/lib/api/controllers/collectionController.js +40 -11
- package/dist/lib/api/controllers/debugController.d.ts +1 -1
- package/dist/lib/api/controllers/documentController.d.ts +137 -28
- package/dist/lib/api/controllers/documentController.js +156 -125
- package/dist/lib/api/controllers/index.d.ts +27 -12
- package/dist/lib/api/controllers/index.js +28 -13
- package/dist/lib/api/controllers/indexController.d.ts +17 -10
- package/dist/lib/api/controllers/indexController.js +13 -11
- package/dist/lib/api/controllers/memoryStorageController.d.ts +2 -5
- package/dist/lib/api/controllers/memoryStorageController.js +199 -127
- package/dist/lib/api/controllers/realtimeController.d.ts +19 -9
- package/dist/lib/api/controllers/realtimeController.js +8 -4
- package/dist/lib/api/controllers/securityController.d.ts +42 -29
- package/dist/lib/api/controllers/securityController.js +35 -19
- package/dist/lib/api/controllers/serverController.d.ts +114 -19
- package/dist/lib/api/controllers/serverController.js +69 -29
- package/dist/lib/api/documentExtractor.d.ts +9 -7
- package/dist/lib/api/documentExtractor.js +105 -41
- package/dist/lib/api/funnel.d.ts +131 -29
- package/dist/lib/api/funnel.js +436 -225
- package/dist/lib/api/httpRoutes.d.ts +16 -11
- package/dist/lib/api/httpRoutes.js +272 -2
- package/dist/lib/api/openapi/OpenApiManager.d.ts +1 -1
- package/dist/lib/api/openapi/openApiGenerator.d.ts +1 -1
- package/dist/lib/api/rateLimiter.d.ts +15 -5
- package/dist/lib/api/rateLimiter.js +42 -14
- package/dist/lib/api/request/kuzzleRequest.d.ts +83 -12
- package/dist/lib/api/request/kuzzleRequest.js +88 -23
- package/dist/lib/api/request/requestContext.d.ts +20 -5
- package/dist/lib/api/request/requestContext.js +14 -4
- package/dist/lib/api/request/requestInput.d.ts +37 -6
- package/dist/lib/api/request/requestInput.js +22 -9
- package/dist/lib/api/request/requestResponse.d.ts +45 -9
- package/dist/lib/api/request/requestResponse.js +34 -3
- package/dist/lib/cluster/command.d.ts +131 -37
- package/dist/lib/cluster/command.js +243 -71
- package/dist/lib/cluster/idCardHandler.d.ts +18 -5
- package/dist/lib/cluster/idCardHandler.js +52 -19
- package/dist/lib/cluster/index.d.ts +8 -2
- package/dist/lib/cluster/index.js +6 -2
- package/dist/lib/cluster/node.d.ts +127 -49
- package/dist/lib/cluster/node.js +412 -179
- package/dist/lib/cluster/protobuf/command.proto +18 -0
- package/dist/lib/cluster/protobuf/commandMessages.d.ts +104 -0
- package/dist/lib/cluster/protobuf/commandMessages.js +30 -0
- package/dist/lib/cluster/protobuf/syncMessages.d.ts +184 -0
- package/dist/lib/cluster/protobuf/syncMessages.js +23 -0
- package/dist/lib/cluster/publisher.d.ts +118 -78
- package/dist/lib/cluster/publisher.js +174 -72
- package/dist/lib/cluster/state.d.ts +15 -9
- package/dist/lib/cluster/state.js +12 -8
- package/dist/lib/cluster/subscriber.d.ts +185 -131
- package/dist/lib/cluster/subscriber.js +357 -95
- package/dist/lib/cluster/workers/IDCardRenewer.d.ts +39 -8
- package/dist/lib/cluster/workers/IDCardRenewer.js +88 -23
- package/dist/lib/config/default.config.d.ts +2 -2
- package/dist/lib/config/default.config.js +10 -3
- package/dist/lib/config/documentEventAliases.d.ts +1 -1
- package/dist/lib/config/index.d.ts +2 -5
- package/dist/lib/config/index.js +30 -17
- package/dist/lib/core/auth/formatProcessing.d.ts +3 -3
- package/dist/lib/core/auth/passportResponse.d.ts +1 -1
- package/dist/lib/core/auth/passportWrapper.d.ts +1 -1
- package/dist/lib/core/auth/passportWrapper.js +14 -13
- package/dist/lib/core/auth/tokenManager.d.ts +24 -3
- package/dist/lib/core/auth/tokenManager.js +47 -19
- package/dist/lib/core/backend/applicationManager.d.ts +2 -2
- package/dist/lib/core/backend/backend.d.ts +16 -5
- package/dist/lib/core/backend/backend.js +14 -6
- package/dist/lib/core/backend/backendCluster.d.ts +1 -1
- package/dist/lib/core/backend/backendConfig.d.ts +17 -5
- package/dist/lib/core/backend/backendConfig.js +1 -0
- package/dist/lib/core/backend/backendController.d.ts +1 -1
- package/dist/lib/core/backend/backendController.js +8 -1
- package/dist/lib/core/backend/backendErrors.d.ts +15 -8
- package/dist/lib/core/backend/backendErrors.js +5 -0
- package/dist/lib/core/backend/backendHook.d.ts +1 -1
- package/dist/lib/core/backend/backendImport.d.ts +1 -1
- package/dist/lib/core/backend/backendOpenApi.d.ts +3 -2
- package/dist/lib/core/backend/backendPipe.d.ts +1 -1
- package/dist/lib/core/backend/backendPipe.js +9 -1
- package/dist/lib/core/backend/backendPlugin.d.ts +2 -2
- package/dist/lib/core/backend/backendSubscription.d.ts +2 -2
- package/dist/lib/core/backend/backendVault.d.ts +1 -1
- package/dist/lib/core/backend/backendVault.js +8 -1
- package/dist/lib/core/cache/cacheEngine.d.ts +7 -4
- package/dist/lib/core/cache/cacheEngine.js +25 -8
- package/dist/lib/core/debug/kuzzleDebugger.d.ts +2 -1
- package/dist/lib/core/debug/kuzzleDebugger.js +31 -17
- package/dist/lib/core/network/accessLogger.d.ts +33 -18
- package/dist/lib/core/network/accessLogger.js +135 -73
- package/dist/lib/core/network/clientConnection.d.ts +13 -11
- package/dist/lib/core/network/clientConnection.js +33 -9
- package/dist/lib/core/network/context.d.ts +17 -22
- package/dist/lib/core/network/context.js +43 -26
- package/dist/lib/core/network/entryPoint.d.ts +38 -16
- package/dist/lib/core/network/entryPoint.js +119 -48
- package/dist/lib/core/network/httpRouter/index.d.ts +20 -50
- package/dist/lib/core/network/httpRouter/index.js +61 -75
- package/dist/lib/core/network/httpRouter/routeHandler.d.ts +17 -32
- package/dist/lib/core/network/httpRouter/routeHandler.js +26 -36
- package/dist/lib/core/network/httpRouter/routePart.d.ts +9 -18
- package/dist/lib/core/network/httpRouter/routePart.js +61 -43
- package/dist/lib/core/network/httpRouter/routeTypes.d.ts +3 -0
- package/dist/lib/core/network/httpRouter/routeTypes.js +23 -0
- package/dist/lib/core/network/networkEntryPoint.d.ts +20 -0
- package/dist/lib/core/network/networkEntryPoint.js +23 -0
- package/dist/lib/core/network/protocolManifest.d.ts +5 -4
- package/dist/lib/core/network/protocolManifest.js +6 -3
- package/dist/lib/core/network/protocols/httpMessage.d.ts +25 -18
- package/dist/lib/core/network/protocols/httpMessage.js +14 -11
- package/dist/lib/core/network/protocols/httpwsProtocol.d.ts +84 -93
- package/dist/lib/core/network/protocols/httpwsProtocol.js +284 -129
- package/dist/lib/core/network/protocols/internalProtocol.d.ts +26 -15
- package/dist/lib/core/network/protocols/internalProtocol.js +17 -16
- package/dist/lib/core/network/protocols/mqttProtocol.d.ts +56 -32
- package/dist/lib/core/network/protocols/mqttProtocol.js +91 -44
- package/dist/lib/core/network/protocols/protocol.d.ts +85 -21
- package/dist/lib/core/network/protocols/protocol.js +83 -27
- package/dist/lib/core/network/router.d.ts +13 -22
- package/dist/lib/core/network/router.js +59 -46
- package/dist/lib/core/plugin/plugin.d.ts +57 -51
- package/dist/lib/core/plugin/plugin.js +218 -103
- package/dist/lib/core/plugin/pluginContext.d.ts +54 -11
- package/dist/lib/core/plugin/pluginContext.js +99 -58
- package/dist/lib/core/plugin/pluginManifest.d.ts +6 -2
- package/dist/lib/core/plugin/pluginManifest.js +18 -11
- package/dist/lib/core/plugin/pluginRepository.d.ts +35 -44
- package/dist/lib/core/plugin/pluginRepository.js +35 -50
- package/dist/lib/core/plugin/pluginsManager.d.ts +128 -46
- package/dist/lib/core/plugin/pluginsManager.js +468 -231
- package/dist/lib/core/plugin/privilegedContext.d.ts +4 -9
- package/dist/lib/core/plugin/privilegedContext.js +5 -10
- package/dist/lib/core/realtime/actionEnum.d.ts +12 -21
- package/dist/lib/core/realtime/actionEnum.js +6 -7
- package/dist/lib/core/realtime/channel.d.ts +11 -5
- package/dist/lib/core/realtime/channel.js +17 -2
- package/dist/lib/core/realtime/connectionRooms.d.ts +2 -2
- package/dist/lib/core/realtime/hotelClerk.d.ts +12 -6
- package/dist/lib/core/realtime/hotelClerk.js +29 -11
- package/dist/lib/core/realtime/index.d.ts +8 -3
- package/dist/lib/core/realtime/index.js +12 -5
- package/dist/lib/core/realtime/notification/document.d.ts +54 -25
- package/dist/lib/core/realtime/notification/document.js +10 -13
- package/dist/lib/core/realtime/notification/index.d.ts +9 -3
- package/dist/lib/core/realtime/notification/index.js +10 -4
- package/dist/lib/core/realtime/notification/server.d.ts +7 -10
- package/dist/lib/core/realtime/notification/server.js +4 -7
- package/dist/lib/core/realtime/notification/user.d.ts +45 -21
- package/dist/lib/core/realtime/notification/user.js +8 -9
- package/dist/lib/core/realtime/notifier.d.ts +52 -40
- package/dist/lib/core/realtime/notifier.js +60 -25
- package/dist/lib/core/realtime/room.d.ts +1 -1
- package/dist/lib/core/realtime/subscription.d.ts +11 -6
- package/dist/lib/core/realtime/subscription.js +5 -1
- package/dist/lib/core/security/index.d.ts +14 -6
- package/dist/lib/core/security/index.js +27 -13
- package/dist/lib/core/security/profileRepository.d.ts +24 -19
- package/dist/lib/core/security/profileRepository.js +23 -10
- package/dist/lib/core/security/roleRepository.d.ts +60 -23
- package/dist/lib/core/security/roleRepository.js +122 -53
- package/dist/lib/core/security/securityLoader.d.ts +33 -18
- package/dist/lib/core/security/securityLoader.js +43 -16
- package/dist/lib/core/security/tokenRepository.d.ts +21 -7
- package/dist/lib/core/security/tokenRepository.js +50 -23
- package/dist/lib/core/security/userRepository.d.ts +44 -21
- package/dist/lib/core/security/userRepository.js +59 -19
- package/dist/lib/core/shared/KoncordeWrapper.d.ts +1 -1
- package/dist/lib/core/shared/ObjectRepository.d.ts +80 -18
- package/dist/lib/core/shared/ObjectRepository.js +57 -29
- package/dist/lib/core/shared/abstractManifest.d.ts +21 -8
- package/dist/lib/core/shared/abstractManifest.js +57 -17
- package/dist/lib/core/shared/sdk/embeddedSdk.d.ts +3 -1
- package/dist/lib/core/shared/sdk/embeddedSdk.js +8 -7
- package/dist/lib/core/shared/sdk/funnelProtocol.d.ts +2 -1
- package/dist/lib/core/shared/sdk/funnelProtocol.js +12 -3
- package/dist/lib/core/shared/sdk/impersonatedSdk.d.ts +11 -5
- package/dist/lib/core/shared/sdk/impersonatedSdk.js +22 -9
- package/dist/lib/core/shared/store.d.ts +45 -29
- package/dist/lib/core/shared/store.js +48 -27
- package/dist/lib/core/statistics/statistics.d.ts +1 -1
- package/dist/lib/core/storage/clientAdapter.d.ts +39 -21
- package/dist/lib/core/storage/clientAdapter.js +88 -48
- package/dist/lib/core/storage/indexCache.d.ts +8 -0
- package/dist/lib/core/storage/indexCache.js +16 -7
- package/dist/lib/core/storage/storageEngine.d.ts +7 -6
- package/dist/lib/core/storage/storageEngine.js +11 -8
- package/dist/lib/core/validation/baseType.d.ts +22 -22
- package/dist/lib/core/validation/baseType.js +11 -26
- package/dist/lib/core/validation/specification.d.ts +148 -0
- package/dist/lib/core/validation/specification.js +34 -0
- package/dist/lib/core/validation/typeOptions.d.ts +62 -0
- package/dist/lib/core/validation/typeOptions.js +23 -0
- package/dist/lib/core/validation/types/anything.d.ts +3 -6
- package/dist/lib/core/validation/types/anything.js +7 -7
- package/dist/lib/core/validation/types/boolean.d.ts +5 -12
- package/dist/lib/core/validation/types/boolean.js +7 -12
- package/dist/lib/core/validation/types/date.d.ts +19 -11
- package/dist/lib/core/validation/types/date.js +212 -161
- package/dist/lib/core/validation/types/email.d.ts +7 -11
- package/dist/lib/core/validation/types/email.js +13 -17
- package/dist/lib/core/validation/types/enum.d.ts +7 -11
- package/dist/lib/core/validation/types/enum.js +39 -20
- package/dist/lib/core/validation/types/geoPoint.d.ts +5 -13
- package/dist/lib/core/validation/types/geoPoint.js +10 -15
- package/dist/lib/core/validation/types/geoShape.d.ts +22 -21
- package/dist/lib/core/validation/types/geoShape.js +113 -129
- package/dist/lib/core/validation/types/geoShapeUtils.d.ts +15 -0
- package/dist/lib/core/validation/types/geoShapeUtils.js +75 -0
- package/dist/lib/core/validation/types/integer.d.ts +7 -5
- package/dist/lib/core/validation/types/integer.js +7 -13
- package/dist/lib/core/validation/types/ipAddress.d.ts +7 -11
- package/dist/lib/core/validation/types/ipAddress.js +13 -17
- package/dist/lib/core/validation/types/numeric.d.ts +7 -11
- package/dist/lib/core/validation/types/numeric.js +22 -29
- package/dist/lib/core/validation/types/object.d.ts +8 -15
- package/dist/lib/core/validation/types/object.js +12 -21
- package/dist/lib/core/validation/types/string.d.ts +7 -11
- package/dist/lib/core/validation/types/string.js +22 -29
- package/dist/lib/core/validation/types/url.d.ts +7 -11
- package/dist/lib/core/validation/types/url.js +14 -18
- package/dist/lib/core/validation/validation.d.ts +119 -80
- package/dist/lib/core/validation/validation.js +470 -412
- package/dist/lib/core/validation/validationUtils.d.ts +31 -0
- package/dist/lib/core/validation/validationUtils.js +190 -0
- package/dist/lib/kerror/codes/4-plugin.json +0 -12
- package/dist/lib/kerror/codes/index.d.ts +12 -2
- package/dist/lib/kerror/codes/index.js +5 -4
- package/dist/lib/kerror/errors/badRequestError.d.ts +1 -1
- package/dist/lib/kerror/errors/badRequestError.js +1 -1
- package/dist/lib/kerror/errors/externalServiceError.d.ts +1 -1
- package/dist/lib/kerror/errors/externalServiceError.js +1 -1
- package/dist/lib/kerror/errors/forbiddenError.d.ts +1 -1
- package/dist/lib/kerror/errors/forbiddenError.js +1 -1
- package/dist/lib/kerror/errors/gatewayTimeoutError.d.ts +1 -1
- package/dist/lib/kerror/errors/gatewayTimeoutError.js +1 -1
- package/dist/lib/kerror/errors/internalError.d.ts +1 -1
- package/dist/lib/kerror/errors/internalError.js +1 -1
- package/dist/lib/kerror/errors/kuzzleError.d.ts +32 -3
- package/dist/lib/kerror/errors/kuzzleError.js +21 -7
- package/dist/lib/kerror/errors/multipleErrorsError.d.ts +2 -2
- package/dist/lib/kerror/errors/multipleErrorsError.js +2 -2
- package/dist/lib/kerror/errors/notFoundError.d.ts +1 -1
- package/dist/lib/kerror/errors/notFoundError.js +1 -1
- package/dist/lib/kerror/errors/partialError.d.ts +8 -2
- package/dist/lib/kerror/errors/partialError.js +22 -9
- package/dist/lib/kerror/errors/pluginImplementationError.d.ts +9 -1
- package/dist/lib/kerror/errors/pluginImplementationError.js +9 -3
- package/dist/lib/kerror/errors/preconditionError.d.ts +1 -1
- package/dist/lib/kerror/errors/preconditionError.js +1 -1
- package/dist/lib/kerror/errors/serviceUnavailableError.d.ts +1 -1
- package/dist/lib/kerror/errors/serviceUnavailableError.js +1 -1
- package/dist/lib/kerror/errors/sizeLimitError.d.ts +1 -1
- package/dist/lib/kerror/errors/sizeLimitError.js +1 -1
- package/dist/lib/kerror/errors/tooManyRequestsError.d.ts +1 -1
- package/dist/lib/kerror/errors/tooManyRequestsError.js +1 -1
- package/dist/lib/kerror/errors/unauthorizedError.d.ts +1 -1
- package/dist/lib/kerror/errors/unauthorizedError.js +1 -1
- package/dist/lib/kerror/index.d.ts +19 -13
- package/dist/lib/kerror/index.js +60 -19
- package/dist/lib/kuzzle/Logger.d.ts +2 -2
- package/dist/lib/kuzzle/dumpGenerator.d.ts +12 -8
- package/dist/lib/kuzzle/dumpGenerator.js +130 -62
- package/dist/lib/kuzzle/event/KuzzleEventEmitter.d.ts +18 -9
- package/dist/lib/kuzzle/event/KuzzleEventEmitter.js +45 -18
- package/dist/lib/kuzzle/event/pipeRunner.d.ts +37 -16
- package/dist/lib/kuzzle/event/pipeRunner.js +73 -26
- package/dist/lib/kuzzle/event/waterfall.d.ts +11 -1
- package/dist/lib/kuzzle/event/waterfall.js +38 -13
- package/dist/lib/kuzzle/internalIndexHandler.d.ts +11 -174
- package/dist/lib/kuzzle/internalIndexHandler.js +58 -29
- package/dist/lib/kuzzle/kuzzle.d.ts +25 -10
- package/dist/lib/kuzzle/kuzzle.js +74 -17
- package/dist/lib/kuzzle/kuzzleStateEnum.d.ts +16 -12
- package/dist/lib/kuzzle/kuzzleStateEnum.js +5 -7
- package/dist/lib/kuzzle/vault.d.ts +5 -1
- package/dist/lib/kuzzle/vault.js +29 -17
- package/dist/lib/model/security/profile.d.ts +34 -5
- package/dist/lib/model/security/profile.js +6 -5
- package/dist/lib/model/security/rights.d.ts +12 -4
- package/dist/lib/model/security/rights.js +7 -6
- package/dist/lib/model/security/role.d.ts +8 -4
- package/dist/lib/model/security/role.js +12 -6
- package/dist/lib/model/security/token.d.ts +8 -0
- package/dist/lib/model/security/user.d.ts +8 -2
- package/dist/lib/model/security/user.js +7 -4
- package/dist/lib/model/storage/apiKey.d.ts +55 -26
- package/dist/lib/model/storage/apiKey.js +97 -24
- package/dist/lib/model/storage/baseModel.d.ts +77 -66
- package/dist/lib/model/storage/baseModel.js +21 -34
- package/dist/lib/service/cache/redis.d.ts +53 -36
- package/dist/lib/service/cache/redis.js +148 -71
- package/dist/lib/service/service.d.ts +14 -19
- package/dist/lib/service/service.js +41 -22
- package/dist/lib/service/storage/7/elasticsearch.d.ts +136 -93
- package/dist/lib/service/storage/7/elasticsearch.js +218 -165
- package/dist/lib/service/storage/7/esWrapper.d.ts +30 -13
- package/dist/lib/service/storage/7/esWrapper.js +58 -37
- package/dist/lib/service/storage/8/elasticsearch.d.ts +153 -119
- package/dist/lib/service/storage/8/elasticsearch.js +286 -213
- package/dist/lib/service/storage/8/esWrapper.d.ts +30 -13
- package/dist/lib/service/storage/8/esWrapper.js +59 -38
- package/dist/lib/service/storage/commons/queryTranslator.d.ts +3 -3
- package/dist/lib/service/storage/commons/queryTranslator.js +71 -35
- package/dist/lib/types/ApiRoute.d.ts +12 -0
- package/dist/lib/types/ApiRoute.js +23 -0
- package/dist/lib/types/ClientConnection.d.ts +1 -1
- package/dist/lib/types/EventHandler.d.ts +10 -0
- package/dist/lib/types/Global.d.ts +8 -3
- package/dist/lib/types/HttpMessage.d.ts +2 -2
- package/dist/lib/types/HttpStream.d.ts +1 -1
- package/dist/lib/types/HttpStream.js +3 -1
- package/dist/lib/types/JSONObject.d.ts +9 -0
- package/dist/lib/types/JSONObject.js +23 -0
- package/dist/lib/types/Kuzzle.d.ts +5 -3
- package/dist/lib/types/KuzzleDocument.d.ts +1 -1
- package/dist/lib/types/KuzzleWebSocket.d.ts +24 -0
- package/dist/lib/types/KuzzleWebSocket.js +23 -0
- package/dist/lib/types/OpenApiDefinition.d.ts +1 -1
- package/dist/lib/types/Plugin.d.ts +33 -8
- package/dist/lib/types/PluginInstance.d.ts +67 -0
- package/dist/lib/types/PluginInstance.js +23 -0
- package/dist/lib/types/Policy.d.ts +1 -1
- package/dist/lib/types/Target.d.ts +8 -0
- package/dist/lib/types/Token.d.ts +14 -2
- package/dist/lib/types/config/HttpConfiguration.d.ts +5 -0
- package/dist/lib/types/config/KuzzleConfiguration.d.ts +102 -1
- package/dist/lib/types/config/PluginsConfiguration.d.ts +3 -2
- package/dist/lib/types/config/SecurityConfiguration.d.ts +6 -2
- package/dist/lib/types/config/ServerConfiguration.d.ts +2 -2
- package/dist/lib/types/config/ServicesConfiguration.d.ts +1 -1
- package/dist/lib/types/config/cache/BaseCacheRedisConfiguration.d.ts +131 -0
- package/dist/lib/types/config/cache/BaseCacheRedisConfiguration.js +3 -0
- package/dist/lib/types/config/internalCache/InternalCacheRedisConfiguration.d.ts +2 -106
- package/dist/lib/types/config/publicCache/PublicCacheRedisConfiguration.d.ts +2 -26
- package/dist/lib/types/config/storageEngine/StorageEngineElasticsearchConfiguration.d.ts +3 -0
- package/dist/lib/types/controllers/Controller.d.ts +12 -3
- package/dist/lib/types/controllers/ControllerDefinition.d.ts +2 -2
- package/dist/lib/types/controllers/{adminControlller.type.js → adminController.type.js} +1 -1
- package/dist/lib/types/controllers/authController.type.d.ts +2 -2
- package/dist/lib/types/core/auth/formatProcessing.type.d.ts +7 -1
- package/dist/lib/types/errors/ErrorDomains.d.ts +1 -1
- package/dist/lib/types/events/EventGenericDocument.d.ts +10 -9
- package/dist/lib/types/events/EventProtocol.d.ts +4 -4
- package/dist/lib/types/index.d.ts +7 -0
- package/dist/lib/types/index.js +7 -0
- package/dist/lib/types/shared/StoreCollectionsDefinition.d.ts +1 -1
- package/dist/lib/types/storage/7/Elasticsearch.d.ts +62 -13
- package/dist/lib/types/storage/8/Elasticsearch.d.ts +62 -13
- package/dist/lib/util/Inflector.d.ts +4 -1
- package/dist/lib/util/Inflector.js +0 -3
- package/dist/lib/util/assertType.d.ts +24 -27
- package/dist/lib/util/assertType.js +28 -39
- package/dist/lib/util/async.js +19 -6
- package/dist/lib/util/asyncStore.js +1 -1
- package/dist/lib/util/bufferedPassThrough.d.ts +9 -0
- package/dist/lib/util/bufferedPassThrough.js +27 -13
- package/dist/lib/util/bytes.d.ts +1 -1
- package/dist/lib/util/bytes.js +6 -2
- package/dist/lib/util/debug.d.ts +3 -1
- package/dist/lib/util/debug.js +42 -10
- package/dist/lib/util/deprecate.d.ts +9 -1
- package/dist/lib/util/deprecate.js +10 -6
- package/dist/lib/util/didYouMean.d.ts +2 -1
- package/dist/lib/util/didYouMean.js +8 -4
- package/dist/lib/util/distributedLock.d.ts +56 -0
- package/dist/lib/util/distributedLock.js +166 -0
- package/dist/lib/util/dump-collection.d.ts +1 -1
- package/dist/lib/util/dump-collection.js +4 -5
- package/dist/lib/util/extractFields.d.ts +15 -11
- package/dist/lib/util/extractFields.js +8 -9
- package/dist/lib/util/koncordeCompat.d.ts +2 -2
- package/dist/lib/util/koncordeCompat.js +33 -0
- package/dist/lib/util/memoize.d.ts +7 -6
- package/dist/lib/util/memoize.js +3 -3
- package/dist/lib/util/mutex.d.ts +22 -2
- package/dist/lib/util/mutex.js +39 -1
- package/dist/lib/util/name-generator.js +14 -2
- package/dist/lib/util/promback.d.ts +20 -11
- package/dist/lib/util/promback.js +14 -7
- package/dist/lib/util/requestAssertions.d.ts +30 -10
- package/dist/lib/util/requestAssertions.js +125 -121
- package/dist/lib/util/safeObject.d.ts +3 -3
- package/dist/lib/util/safeObject.js +7 -3
- package/dist/lib/util/stackTrace.d.ts +13 -5
- package/dist/lib/util/stackTrace.js +17 -12
- package/dist/lib/util/thrown.d.ts +13 -0
- package/dist/lib/util/thrown.js +46 -0
- package/dist/package.json +26 -19
- package/package.json +26 -19
- package/dist/lib/util/wildcard.d.ts +0 -1
- package/dist/lib/util/wildcard.js +0 -46
- /package/dist/lib/types/controllers/{adminControlller.type.d.ts → adminController.type.d.ts} +0 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Kuzzle, a backend software, self-hostable and ready to use
|
|
4
|
+
* to power modern apps
|
|
5
|
+
*
|
|
6
|
+
* Copyright 2015-2022 Kuzzle
|
|
7
|
+
* mailto: support AT kuzzle.io
|
|
8
|
+
* website: http://kuzzle.io
|
|
9
|
+
*
|
|
10
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
11
|
+
* you may not use this file except in compliance with the License.
|
|
12
|
+
* You may obtain a copy of the License at
|
|
13
|
+
*
|
|
14
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
15
|
+
*
|
|
16
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
18
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
19
|
+
* See the License for the specific language governing permissions and
|
|
20
|
+
* limitations under the License.
|
|
21
|
+
*/
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.withLock = exports.MutexLockLostError = void 0;
|
|
27
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
28
|
+
const redis_semaphore_1 = require("redis-semaphore");
|
|
29
|
+
const debug_1 = __importDefault(require("./debug"));
|
|
30
|
+
require("../types/Global");
|
|
31
|
+
const debug = (0, debug_1.default)("kuzzle:distributedLock");
|
|
32
|
+
/**
|
|
33
|
+
* Thrown when a lock acquired by `withLock` is lost while its callback is
|
|
34
|
+
* still running (e.g. TTL extension failed and another node may now hold
|
|
35
|
+
* the lock).
|
|
36
|
+
*/
|
|
37
|
+
class MutexLockLostError extends Error {
|
|
38
|
+
constructor(key, cause) {
|
|
39
|
+
super(`Lock lost for resource "${key}"`, cause ? { cause } : undefined);
|
|
40
|
+
this.name = "MutexLockLostError";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.MutexLockLostError = MutexLockLostError;
|
|
44
|
+
/**
|
|
45
|
+
* redis-semaphore's mutex, adjusted to what `withLock` promises:
|
|
46
|
+
*
|
|
47
|
+
* - the lock lives under the resource key itself, as with the deprecated
|
|
48
|
+
* `Mutex` class (redis-semaphore would prefix it with "mutex:"), so both
|
|
49
|
+
* still contend on the same Redis key;
|
|
50
|
+
* - a TTL extension that fails with a Redis error counts as a lost lock
|
|
51
|
+
* (redis-semaphore would let the error escape its refresh timer as an
|
|
52
|
+
* unhandled rejection, without knowing whether the lock is still held).
|
|
53
|
+
* The error is kept, to be reported as the loss's cause.
|
|
54
|
+
*/
|
|
55
|
+
class ResourceMutex extends redis_semaphore_1.Mutex {
|
|
56
|
+
constructor(client, key, options) {
|
|
57
|
+
super(client, key, options);
|
|
58
|
+
this._key = key;
|
|
59
|
+
}
|
|
60
|
+
async _refresh() {
|
|
61
|
+
try {
|
|
62
|
+
return await super._refresh();
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
this.refreshError =
|
|
66
|
+
error instanceof Error ? error : new Error(String(error));
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Tracks, per async context, the set of lock keys already held by an
|
|
73
|
+
* ancestor `withLock` call. Deliberately separate from the shared
|
|
74
|
+
* `global.kuzzle.asyncStore`: that store always seeds a fresh Map on
|
|
75
|
+
* `.run()` (it would silently discard whatever the parent context held) and
|
|
76
|
+
* throws if no context is active yet (which would break locking used
|
|
77
|
+
* outside a request scope, e.g. during boot or in background jobs).
|
|
78
|
+
*/
|
|
79
|
+
const lockContext = new node_async_hooks_1.AsyncLocalStorage();
|
|
80
|
+
let clientPromise;
|
|
81
|
+
/**
|
|
82
|
+
* Lazily fetches and memoizes the internal cache's raw ioredis client.
|
|
83
|
+
* Self-healing: if the very first call happens before the cache engine has
|
|
84
|
+
* registered its ask handler (e.g. from an early plugin lifecycle hook), the
|
|
85
|
+
* failure is not cached, so the next call retries instead of permanently
|
|
86
|
+
* failing for the rest of the process.
|
|
87
|
+
*/
|
|
88
|
+
async function getClient() {
|
|
89
|
+
clientPromise ?? (clientPromise = (async () => global.kuzzle.ask("core:cache:internal:client:get"))().catch((err) => {
|
|
90
|
+
clientPromise = undefined;
|
|
91
|
+
throw err;
|
|
92
|
+
}));
|
|
93
|
+
return clientPromise;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Runs `callback` while holding a distributed, reentrant lock on `key`.
|
|
97
|
+
*
|
|
98
|
+
* Reentrant: if the current async context already holds `key` (i.e. this is
|
|
99
|
+
* a nested call from inside another `withLock(key, ...)` call for the same
|
|
100
|
+
* key), `callback` runs immediately with no new Redis round-trip, and
|
|
101
|
+
* `config` is silently ignored (the ancestor's lock/TTL/retry settings
|
|
102
|
+
* apply — this is correct reentrant-mutex semantics, not a bug).
|
|
103
|
+
*
|
|
104
|
+
* The lock's TTL is extended in the background while `callback` runs. If
|
|
105
|
+
* the lock cannot be acquired within `retryAttempts + 1` attempts, the
|
|
106
|
+
* returned promise rejects without running `callback`.
|
|
107
|
+
*
|
|
108
|
+
* If the lock is lost mid-callback (e.g. TTL extension failed and another
|
|
109
|
+
* node may now hold it), the returned promise rejects with
|
|
110
|
+
* `MutexLockLostError` as soon as that's detected. `callback` itself cannot
|
|
111
|
+
* be cancelled and keeps running in the background; do not perform
|
|
112
|
+
* authoritative side effects after observing this rejection.
|
|
113
|
+
*
|
|
114
|
+
* Do not use on the same resource key as the deprecated `Mutex` class
|
|
115
|
+
* concurrently: both write to the same Redis key with incompatible
|
|
116
|
+
* value/TTL formats and will contend with (but never corrupt) each other.
|
|
117
|
+
*
|
|
118
|
+
* @param key - resource identifier to be locked (must be identical across
|
|
119
|
+
* all nodes)
|
|
120
|
+
* @param callback - executed while the lock is held
|
|
121
|
+
* @param config - lock options (ignored if this call is reentrant)
|
|
122
|
+
*/
|
|
123
|
+
async function withLock(key, callback, config = {}) {
|
|
124
|
+
const held = lockContext.getStore();
|
|
125
|
+
if (held?.has(key)) {
|
|
126
|
+
return callback();
|
|
127
|
+
}
|
|
128
|
+
const { retryAttempts = 10, retryDelay = 200, ttl = 30000 } = config;
|
|
129
|
+
const client = await getClient();
|
|
130
|
+
const loss = new AbortController();
|
|
131
|
+
const lockLost = new Promise((_resolve, reject) => {
|
|
132
|
+
loss.signal.addEventListener("abort", () => reject(loss.signal.reason), {
|
|
133
|
+
once: true,
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
// Only ever observed through the race below; never an unhandled rejection
|
|
137
|
+
lockLost.catch(() => undefined);
|
|
138
|
+
const mutex = new ResourceMutex(client, key, {
|
|
139
|
+
acquireAttemptsLimit: retryAttempts + 1,
|
|
140
|
+
acquireTimeout: Number.POSITIVE_INFINITY,
|
|
141
|
+
lockTimeout: ttl,
|
|
142
|
+
onLockLost: (error) => {
|
|
143
|
+
loss.abort(new MutexLockLostError(key, mutex.refreshError ?? error));
|
|
144
|
+
},
|
|
145
|
+
retryInterval: retryDelay,
|
|
146
|
+
});
|
|
147
|
+
if (!(await mutex.tryAcquire())) {
|
|
148
|
+
throw new Error(`Failed to acquire lock "${key}" after ${retryAttempts + 1} attempts`);
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
const nextHeld = new Set(held);
|
|
152
|
+
nextHeld.add(key);
|
|
153
|
+
const callbackPromise = lockContext.run(nextHeld, () => callback());
|
|
154
|
+
// Settles as soon as the lock is lost, without waiting for the callback
|
|
155
|
+
return await Promise.race([callbackPromise, lockLost]);
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
// A failed release only leaves the key to expire with its TTL: it must
|
|
159
|
+
// not replace the callback's own outcome
|
|
160
|
+
await mutex.release().catch((error) => {
|
|
161
|
+
debug("Failed to release lock %s: %s", key, error);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
exports.withLock = withLock;
|
|
166
|
+
//# sourceMappingURL=distributedLock.js.map
|
|
@@ -58,10 +58,7 @@ function flattenObject(target) {
|
|
|
58
58
|
}
|
|
59
59
|
exports.flattenObject = flattenObject;
|
|
60
60
|
function flattenStep(output, object, prev = null) {
|
|
61
|
-
const
|
|
62
|
-
for (let i = 0; i < keys.length; i++) {
|
|
63
|
-
const key = keys[i];
|
|
64
|
-
const value = object[key];
|
|
61
|
+
for (const [key, value] of Object.entries(object)) {
|
|
65
62
|
const newKey = prev ? prev + "." + key : key;
|
|
66
63
|
if (Object.prototype.toString.call(value) === "[object Object]") {
|
|
67
64
|
flattenStep(output, value, newKey);
|
|
@@ -130,6 +127,8 @@ class AbstractDumper {
|
|
|
130
127
|
this.query = query;
|
|
131
128
|
this.writeStream = writeStream;
|
|
132
129
|
this.options = options;
|
|
130
|
+
/** Set by `setup()`, before any document is written. */
|
|
131
|
+
this.collectionDir = "";
|
|
133
132
|
if (!writeStream) {
|
|
134
133
|
throw kerror.get("api", "assert", "missing_argument", "writeStream");
|
|
135
134
|
}
|
|
@@ -197,7 +196,7 @@ class AbstractDumper {
|
|
|
197
196
|
await this.tearDown();
|
|
198
197
|
}
|
|
199
198
|
catch (e) {
|
|
200
|
-
this.writeStream.write(e
|
|
199
|
+
this.writeStream.write(String(e));
|
|
201
200
|
}
|
|
202
201
|
this.writeStream.end();
|
|
203
202
|
return waitWrite;
|
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
interface ExtractedField {
|
|
2
|
+
key: string;
|
|
3
|
+
value: unknown;
|
|
4
|
+
}
|
|
2
5
|
/**
|
|
3
6
|
* Extract nested fields of an object in a flat array.
|
|
4
7
|
* Example: { field : { 1: "nested", 2: "nested" } } => [ 'field.1', 'field.2' ]
|
|
5
8
|
*
|
|
6
|
-
* @param
|
|
7
|
-
* @param
|
|
9
|
+
* @param document - Document to extract fields from
|
|
10
|
+
* @param options - alsoExtractValues (false), fieldsToIgnore ( [ ] )
|
|
8
11
|
*
|
|
9
|
-
* @returns
|
|
12
|
+
* @returns Array of field paths, or of { key, value } pairs when alsoExtractValues is true
|
|
10
13
|
*/
|
|
11
|
-
declare function extractFields(document:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}>;
|
|
14
|
+
declare function extractFields(document: Record<string, unknown>, { fieldsToIgnore, alsoExtractValues, }?: {
|
|
15
|
+
fieldsToIgnore?: string[];
|
|
16
|
+
alsoExtractValues?: boolean;
|
|
17
|
+
}, { path, extractedFields, }?: {
|
|
18
|
+
path?: string | null;
|
|
19
|
+
extractedFields?: Array<string | ExtractedField>;
|
|
20
|
+
}): Array<string | ExtractedField>;
|
|
21
|
+
export = extractFields;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*
|
|
2
3
|
* Kuzzle, a backend software, self-hostable and ready to use
|
|
3
4
|
* to power modern apps
|
|
@@ -18,25 +19,23 @@
|
|
|
18
19
|
* See the License for the specific language governing permissions and
|
|
19
20
|
* limitations under the License.
|
|
20
21
|
*/
|
|
21
|
-
|
|
22
|
-
const { isPlainObject } = require("./safeObject");
|
|
22
|
+
const safeObject_1 = require("./safeObject");
|
|
23
23
|
/**
|
|
24
24
|
* Extract nested fields of an object in a flat array.
|
|
25
25
|
* Example: { field : { 1: "nested", 2: "nested" } } => [ 'field.1', 'field.2' ]
|
|
26
26
|
*
|
|
27
|
-
* @param
|
|
28
|
-
* @param
|
|
27
|
+
* @param document - Document to extract fields from
|
|
28
|
+
* @param options - alsoExtractValues (false), fieldsToIgnore ( [ ] )
|
|
29
29
|
*
|
|
30
|
-
* @returns
|
|
30
|
+
* @returns Array of field paths, or of { key, value } pairs when alsoExtractValues is true
|
|
31
31
|
*/
|
|
32
|
-
function extractFields(document, { fieldsToIgnore = [], alsoExtractValues = false } = {}, { path = null, extractedFields = [] } = {}) {
|
|
32
|
+
function extractFields(document, { fieldsToIgnore = [], alsoExtractValues = false, } = {}, { path = null, extractedFields = [], } = {}) {
|
|
33
33
|
for (const [key, value] of Object.entries(document)) {
|
|
34
|
-
if (fieldsToIgnore.
|
|
35
|
-
fieldsToIgnore.find((keyToIgnore) => keyToIgnore === key)) {
|
|
34
|
+
if (fieldsToIgnore.includes(key)) {
|
|
36
35
|
continue;
|
|
37
36
|
}
|
|
38
37
|
const currentPath = path ? `${path}.${key}` : key;
|
|
39
|
-
if (isPlainObject(value)) {
|
|
38
|
+
if ((0, safeObject_1.isPlainObject)(value)) {
|
|
40
39
|
extractFields(value, { alsoExtractValues, fieldsToIgnore }, { extractedFields, path: currentPath });
|
|
41
40
|
}
|
|
42
41
|
else if (alsoExtractValues) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { JSONObject } from "
|
|
2
|
-
import { Koncorde } from "koncorde";
|
|
1
|
+
import type { JSONObject } from "../types/JSONObject";
|
|
2
|
+
import type { Koncorde } from "koncorde";
|
|
3
3
|
/**
|
|
4
4
|
* Builds a Koncorde v4 index name from the old fashioned index+collection
|
|
5
5
|
* arguments
|
|
@@ -19,14 +19,39 @@
|
|
|
19
19
|
* See the License for the specific language governing permissions and
|
|
20
20
|
* limitations under the License.
|
|
21
21
|
*/
|
|
22
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
25
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
26
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
27
|
+
}
|
|
28
|
+
Object.defineProperty(o, k2, desc);
|
|
29
|
+
}) : (function(o, m, k, k2) {
|
|
30
|
+
if (k2 === undefined) k2 = k;
|
|
31
|
+
o[k2] = m[k];
|
|
32
|
+
}));
|
|
33
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
34
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
35
|
+
}) : function(o, v) {
|
|
36
|
+
o["default"] = v;
|
|
37
|
+
});
|
|
38
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
22
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
46
|
exports.getIndexes = exports.getCollections = exports.koncordeTest = exports.fromKoncordeIndex = exports.toKoncordeIndex = void 0;
|
|
24
47
|
/*
|
|
25
48
|
Set of utility functions meant to ease up the use of Koncorde v4 in Kuzzle
|
|
26
49
|
*/
|
|
27
50
|
const lodash_1 = require("lodash");
|
|
51
|
+
const kerror = __importStar(require("../kerror"));
|
|
28
52
|
// No collision possible: "/" is forbidden in index (or collection) names
|
|
29
53
|
const SEPARATOR = "/";
|
|
54
|
+
const fatal = kerror.wrap("core", "fatal");
|
|
30
55
|
/**
|
|
31
56
|
* Builds a Koncorde v4 index name from the old fashioned index+collection
|
|
32
57
|
* arguments
|
|
@@ -47,6 +72,14 @@ exports.toKoncordeIndex = toKoncordeIndex;
|
|
|
47
72
|
*/
|
|
48
73
|
function fromKoncordeIndex(index) {
|
|
49
74
|
const [kindex, kcollection] = index.split(SEPARATOR);
|
|
75
|
+
// `split` always yields a first element, but a second one exists only if the
|
|
76
|
+
// name really is a v4 pair. Two of the three callers read it off a cluster
|
|
77
|
+
// message payload — remote input — so a name without the separator is
|
|
78
|
+
// reachable, and answering it with `collection: undefined` would hand the
|
|
79
|
+
// question to every caller instead of to the node that sent a bad name.
|
|
80
|
+
if (kindex === undefined || kcollection === undefined) {
|
|
81
|
+
throw fatal.get("assertion_failed", `"${index}" is not a Koncorde index`);
|
|
82
|
+
}
|
|
50
83
|
return {
|
|
51
84
|
collection: kcollection,
|
|
52
85
|
index: kindex,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
interface Memoized<Args extends unknown[], Result> {
|
|
2
|
+
(...args: Args): Result;
|
|
3
|
+
fn: (...args: Args) => Result;
|
|
4
|
+
cache: Map<unknown, Result>;
|
|
5
|
+
resolver: ((args: Args) => unknown) | null;
|
|
6
|
+
}
|
|
7
|
+
declare function memoize<Args extends unknown[], Result>(fn: (...args: Args) => Result, resolver?: ((args: Args) => unknown) | null): Memoized<Args, Result>;
|
|
1
8
|
export = memoize;
|
|
2
|
-
declare function memoize(fn: any, resolver?: any): {
|
|
3
|
-
(...args: any[]): any;
|
|
4
|
-
fn: any;
|
|
5
|
-
cache: Map<any, any>;
|
|
6
|
-
resolver: any;
|
|
7
|
-
};
|
package/dist/lib/util/memoize.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*
|
|
2
3
|
* Kuzzle, a backend software, self-hostable and ready to use
|
|
3
4
|
* to power modern apps
|
|
@@ -18,9 +19,8 @@
|
|
|
18
19
|
* See the License for the specific language governing permissions and
|
|
19
20
|
* limitations under the License.
|
|
20
21
|
*/
|
|
21
|
-
"use strict";
|
|
22
22
|
function memoize(fn, resolver = null) {
|
|
23
|
-
const memoized = (...args) => {
|
|
23
|
+
const memoized = ((...args) => {
|
|
24
24
|
const key = memoized.resolver !== null ? memoized.resolver(args) : args[0];
|
|
25
25
|
let result = memoized.cache.get(key);
|
|
26
26
|
if (result === undefined) {
|
|
@@ -28,7 +28,7 @@ function memoize(fn, resolver = null) {
|
|
|
28
28
|
memoized.cache.set(key, result);
|
|
29
29
|
}
|
|
30
30
|
return result;
|
|
31
|
-
};
|
|
31
|
+
});
|
|
32
32
|
memoized.fn = fn;
|
|
33
33
|
memoized.cache = new Map();
|
|
34
34
|
memoized.resolver = resolver;
|
package/dist/lib/util/mutex.d.ts
CHANGED
|
@@ -33,6 +33,12 @@ export interface MutexOptions {
|
|
|
33
33
|
* If, in the future, Kuzzle is able to support multiple independant
|
|
34
34
|
* Redis servers, then this class needs to implement redlock to properly handle
|
|
35
35
|
* synchronization between servers (see https://redis.io/topics/distlock)
|
|
36
|
+
*
|
|
37
|
+
* @deprecated Use `withLock` from `./distributedLock` instead: it supports
|
|
38
|
+
* real Redlock semantics and reentrancy. Do not mix `Mutex` and `withLock`
|
|
39
|
+
* on the same resource key — they use incompatible acquisition/TTL formats
|
|
40
|
+
* and will contend with (though never corrupt) each other's lock on that
|
|
41
|
+
* key.
|
|
36
42
|
*/
|
|
37
43
|
export declare class Mutex {
|
|
38
44
|
readonly resource: string;
|
|
@@ -81,8 +87,22 @@ export declare class Mutex {
|
|
|
81
87
|
* @return {Promise.<boolean>} True if the ressource has been unlocked before the `timeout`
|
|
82
88
|
*/
|
|
83
89
|
wait({ attemptDelay, timeout, }: {
|
|
84
|
-
attemptDelay?: number;
|
|
85
|
-
timeout?: number;
|
|
90
|
+
attemptDelay?: number | undefined;
|
|
91
|
+
timeout?: number | undefined;
|
|
86
92
|
}): Promise<boolean>;
|
|
93
|
+
/**
|
|
94
|
+
* Frees every lock this process holds, and stops it from taking new ones.
|
|
95
|
+
* Only meant to be called right before `process.exit`.
|
|
96
|
+
*
|
|
97
|
+
* A process that exits holding a lock leaves it in Redis until its ttl
|
|
98
|
+
* expires, and every node waiting on it waits that long. That is how a
|
|
99
|
+
* node evicted while starting its plugins made another node time out
|
|
100
|
+
* starting its own, and leave the cluster too (step 15, F-13).
|
|
101
|
+
*
|
|
102
|
+
* From then on, `lock()` never resolves: the process is about to exit, and
|
|
103
|
+
* answering `false` would send its caller down a path meant for a lock
|
|
104
|
+
* held by another node.
|
|
105
|
+
*/
|
|
106
|
+
static releaseAllBeforeExit(): Promise<void>;
|
|
87
107
|
get locked(): boolean;
|
|
88
108
|
}
|
package/dist/lib/util/mutex.js
CHANGED
|
@@ -68,6 +68,10 @@ end
|
|
|
68
68
|
// Global: we need to register the LUA script only once. This variable is used
|
|
69
69
|
// to keep track of whether the script was already registered or not
|
|
70
70
|
let delScriptRegistered = false;
|
|
71
|
+
// Every lock this process holds, so that it can give them back before it
|
|
72
|
+
// exits (see `Mutex.releaseAllBeforeExit`).
|
|
73
|
+
const held = new Set(); // NOSONAR: deprecated for callers, not for itself
|
|
74
|
+
let exiting = false;
|
|
71
75
|
/**
|
|
72
76
|
* Mutex meant to work across a kuzzle cluster.
|
|
73
77
|
*
|
|
@@ -83,6 +87,12 @@ let delScriptRegistered = false;
|
|
|
83
87
|
* If, in the future, Kuzzle is able to support multiple independant
|
|
84
88
|
* Redis servers, then this class needs to implement redlock to properly handle
|
|
85
89
|
* synchronization between servers (see https://redis.io/topics/distlock)
|
|
90
|
+
*
|
|
91
|
+
* @deprecated Use `withLock` from `./distributedLock` instead: it supports
|
|
92
|
+
* real Redlock semantics and reentrancy. Do not mix `Mutex` and `withLock`
|
|
93
|
+
* on the same resource key — they use incompatible acquisition/TTL formats
|
|
94
|
+
* and will contend with (though never corrupt) each other's lock on that
|
|
95
|
+
* key.
|
|
86
96
|
*/
|
|
87
97
|
class Mutex {
|
|
88
98
|
/**
|
|
@@ -114,6 +124,9 @@ class Mutex {
|
|
|
114
124
|
if (this._locked) {
|
|
115
125
|
throw fatal.get("assertion_failed", `resource "${this.resource}" already locked by this mutex (id: ${this.mutexId})`);
|
|
116
126
|
}
|
|
127
|
+
if (exiting) {
|
|
128
|
+
return new Promise(() => { });
|
|
129
|
+
}
|
|
117
130
|
let duration = 0;
|
|
118
131
|
do {
|
|
119
132
|
this._locked = await global.kuzzle.ask("core:cache:internal:store", this.resource, this.mutexId, { onlyIfNew: true, ttl: this.ttl });
|
|
@@ -127,6 +140,12 @@ class Mutex {
|
|
|
127
140
|
debug("Failed to lock %s (mutex id: %s)", this.resource, this.mutexId);
|
|
128
141
|
return false;
|
|
129
142
|
}
|
|
143
|
+
held.add(this);
|
|
144
|
+
// Acquired while `releaseAllBeforeExit` was running: give it back at once.
|
|
145
|
+
if (exiting) {
|
|
146
|
+
await this.unlock();
|
|
147
|
+
return new Promise(() => { });
|
|
148
|
+
}
|
|
130
149
|
debug("Resource %s locked (mutex id: %s)", this.resource, this.mutexId);
|
|
131
150
|
return true;
|
|
132
151
|
}
|
|
@@ -145,6 +164,7 @@ class Mutex {
|
|
|
145
164
|
}
|
|
146
165
|
await global.kuzzle.ask("core:cache:internal:script:execute", "delIfValueEqual", this.resource, this.mutexId);
|
|
147
166
|
this._locked = false;
|
|
167
|
+
held.delete(this);
|
|
148
168
|
debug("Resource %s freed (mutex id: %s)", this.resource, this.mutexId);
|
|
149
169
|
}
|
|
150
170
|
/**
|
|
@@ -163,7 +183,7 @@ class Mutex {
|
|
|
163
183
|
*/
|
|
164
184
|
async wait({ attemptDelay = this.attemptDelay, timeout = this.timeout, }) {
|
|
165
185
|
let duration = 0;
|
|
166
|
-
let isLocked
|
|
186
|
+
let isLocked;
|
|
167
187
|
do {
|
|
168
188
|
isLocked = await global.kuzzle.ask("core:cache:internal:get", this.resource);
|
|
169
189
|
duration += attemptDelay;
|
|
@@ -173,6 +193,24 @@ class Mutex {
|
|
|
173
193
|
} while (isLocked && (timeout === -1 || duration <= timeout));
|
|
174
194
|
return !isLocked;
|
|
175
195
|
}
|
|
196
|
+
/**
|
|
197
|
+
* Frees every lock this process holds, and stops it from taking new ones.
|
|
198
|
+
* Only meant to be called right before `process.exit`.
|
|
199
|
+
*
|
|
200
|
+
* A process that exits holding a lock leaves it in Redis until its ttl
|
|
201
|
+
* expires, and every node waiting on it waits that long. That is how a
|
|
202
|
+
* node evicted while starting its plugins made another node time out
|
|
203
|
+
* starting its own, and leave the cluster too (step 15, F-13).
|
|
204
|
+
*
|
|
205
|
+
* From then on, `lock()` never resolves: the process is about to exit, and
|
|
206
|
+
* answering `false` would send its caller down a path meant for a lock
|
|
207
|
+
* held by another node.
|
|
208
|
+
*/
|
|
209
|
+
static async releaseAllBeforeExit() {
|
|
210
|
+
exiting = true;
|
|
211
|
+
// Best effort: a lock that cannot be freed still expires with its ttl.
|
|
212
|
+
await Promise.allSettled([...held].map((mutex) => mutex.unlock()));
|
|
213
|
+
}
|
|
176
214
|
get locked() {
|
|
177
215
|
return this._locked;
|
|
178
216
|
}
|
|
@@ -34,7 +34,7 @@ class NameGenerator {
|
|
|
34
34
|
* @returns a random name
|
|
35
35
|
*/
|
|
36
36
|
static getRandomName() {
|
|
37
|
-
return
|
|
37
|
+
return randomItem(names);
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
40
|
* Returns a random adjective.
|
|
@@ -48,7 +48,7 @@ class NameGenerator {
|
|
|
48
48
|
* @returns a random adjective
|
|
49
49
|
*/
|
|
50
50
|
static getRandomAdjective() {
|
|
51
|
-
return
|
|
51
|
+
return randomItem(adjectives);
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
54
|
* Generates a random formatted name that consists of an optional prefix, a random adjective,
|
|
@@ -99,6 +99,18 @@ function randomNumber(min, max) {
|
|
|
99
99
|
return Math.floor(Math.random() * (max - min)) + min;
|
|
100
100
|
}
|
|
101
101
|
exports.randomNumber = randomNumber;
|
|
102
|
+
/**
|
|
103
|
+
* Picks one of `items` at random.
|
|
104
|
+
*
|
|
105
|
+
* `items[i]` is `T | undefined` under `noUncheckedIndexedAccess` whatever the
|
|
106
|
+
* index — a tuple type does not help, the index is still a `number`. The head,
|
|
107
|
+
* whose index IS a literal and is therefore typed `T`, stands in for the
|
|
108
|
+
* out-of-range read that cannot happen. No assertion, and no branch claiming a
|
|
109
|
+
* runtime state that does not exist: the lists below are non-empty by type.
|
|
110
|
+
*/
|
|
111
|
+
function randomItem(items) {
|
|
112
|
+
return items[randomNumber(items.length)] ?? items[0];
|
|
113
|
+
}
|
|
102
114
|
const adjectives = [
|
|
103
115
|
"aback",
|
|
104
116
|
"abandoned",
|
|
@@ -1,13 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import Bluebird from "bluebird";
|
|
2
|
+
type PrombackCallback<T> = (error: unknown, result?: T) => void;
|
|
3
|
+
/**
|
|
4
|
+
* `resolve()` may be called with no argument, and callers do pass a possibly
|
|
5
|
+
* missing value (`promback.resolve(updated[0])` under
|
|
6
|
+
* `noUncheckedIndexedAccess`), so the settled value is `T | undefined` — not
|
|
7
|
+
* `T`. Declaring it honestly is what lets `resolve`/`reject` type-check
|
|
8
|
+
* without a cast.
|
|
9
|
+
*/
|
|
10
|
+
type PrombackResult<T> = T | undefined;
|
|
11
|
+
declare class Promback<T = unknown> {
|
|
12
|
+
private readonly _callback;
|
|
13
|
+
private _resolve;
|
|
14
|
+
private _reject;
|
|
15
|
+
deferred: Bluebird<PrombackResult<T>> | null;
|
|
8
16
|
isPromise: boolean;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
17
|
+
constructor(callback?: PrombackCallback<T> | null);
|
|
18
|
+
resolve(result?: T): Bluebird<PrombackResult<T>> | null;
|
|
19
|
+
reject(error?: unknown): Bluebird<PrombackResult<T>> | null;
|
|
20
|
+
get promise(): Bluebird<PrombackResult<T>> | null;
|
|
12
21
|
}
|
|
13
|
-
|
|
22
|
+
export = Promback;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*
|
|
2
3
|
* Kuzzle, a backend software, self-hostable and ready to use
|
|
3
4
|
* to power modern apps
|
|
@@ -18,8 +19,10 @@
|
|
|
18
19
|
* See the License for the specific language governing permissions and
|
|
19
20
|
* limitations under the License.
|
|
20
21
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
|
23
26
|
class Promback {
|
|
24
27
|
constructor(callback = null) {
|
|
25
28
|
this._callback = callback;
|
|
@@ -28,27 +31,31 @@ class Promback {
|
|
|
28
31
|
this.deferred = null;
|
|
29
32
|
this.isPromise = this._callback === null;
|
|
30
33
|
if (this.isPromise) {
|
|
31
|
-
this.deferred = new
|
|
34
|
+
this.deferred = new bluebird_1.default((res, rej) => {
|
|
32
35
|
this._resolve = res;
|
|
33
36
|
this._reject = rej;
|
|
34
37
|
});
|
|
35
38
|
}
|
|
36
39
|
}
|
|
37
40
|
resolve(result) {
|
|
38
|
-
|
|
41
|
+
// Narrowing on the settler rather than on `isPromise` is equivalent — the
|
|
42
|
+
// Bluebird executor runs synchronously, so `_resolve` is set if and only
|
|
43
|
+
// if no callback was given — and it is what makes the two branches
|
|
44
|
+
// provably non-null.
|
|
45
|
+
if (this._resolve !== null) {
|
|
39
46
|
this._resolve(result);
|
|
40
47
|
}
|
|
41
48
|
else {
|
|
42
|
-
this._callback(null, result);
|
|
49
|
+
this._callback?.(null, result);
|
|
43
50
|
}
|
|
44
51
|
return this.deferred;
|
|
45
52
|
}
|
|
46
53
|
reject(error) {
|
|
47
|
-
if (this.
|
|
54
|
+
if (this._reject !== null) {
|
|
48
55
|
this._reject(error);
|
|
49
56
|
}
|
|
50
57
|
else {
|
|
51
|
-
this._callback(error);
|
|
58
|
+
this._callback?.(error);
|
|
52
59
|
}
|
|
53
60
|
return this.deferred;
|
|
54
61
|
}
|