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.
Files changed (408) hide show
  1. package/dist/bin/copy-binaries.js +71 -4
  2. package/dist/bin/start-kuzzle-server +191 -97
  3. package/dist/index.d.ts +31 -1
  4. package/dist/index.js +45 -2
  5. package/dist/lib/api/controllers/adminController.d.ts +4 -3
  6. package/dist/lib/api/controllers/adminController.js +1 -2
  7. package/dist/lib/api/controllers/authController.d.ts +37 -16
  8. package/dist/lib/api/controllers/authController.js +88 -39
  9. package/dist/lib/api/controllers/baseController.d.ts +10 -5
  10. package/dist/lib/api/controllers/baseController.js +36 -15
  11. package/dist/lib/api/controllers/bulkController.d.ts +11 -7
  12. package/dist/lib/api/controllers/bulkController.js +28 -5
  13. package/dist/lib/api/controllers/clusterController.d.ts +2 -2
  14. package/dist/lib/api/controllers/clusterController.js +3 -3
  15. package/dist/lib/api/controllers/collectionController.d.ts +57 -21
  16. package/dist/lib/api/controllers/collectionController.js +40 -11
  17. package/dist/lib/api/controllers/debugController.d.ts +1 -1
  18. package/dist/lib/api/controllers/documentController.d.ts +137 -28
  19. package/dist/lib/api/controllers/documentController.js +156 -125
  20. package/dist/lib/api/controllers/index.d.ts +27 -12
  21. package/dist/lib/api/controllers/index.js +28 -13
  22. package/dist/lib/api/controllers/indexController.d.ts +17 -10
  23. package/dist/lib/api/controllers/indexController.js +13 -11
  24. package/dist/lib/api/controllers/memoryStorageController.d.ts +2 -5
  25. package/dist/lib/api/controllers/memoryStorageController.js +199 -127
  26. package/dist/lib/api/controllers/realtimeController.d.ts +19 -9
  27. package/dist/lib/api/controllers/realtimeController.js +8 -4
  28. package/dist/lib/api/controllers/securityController.d.ts +42 -29
  29. package/dist/lib/api/controllers/securityController.js +35 -19
  30. package/dist/lib/api/controllers/serverController.d.ts +114 -19
  31. package/dist/lib/api/controllers/serverController.js +69 -29
  32. package/dist/lib/api/documentExtractor.d.ts +9 -7
  33. package/dist/lib/api/documentExtractor.js +105 -41
  34. package/dist/lib/api/funnel.d.ts +131 -29
  35. package/dist/lib/api/funnel.js +436 -225
  36. package/dist/lib/api/httpRoutes.d.ts +16 -11
  37. package/dist/lib/api/httpRoutes.js +272 -2
  38. package/dist/lib/api/openapi/OpenApiManager.d.ts +1 -1
  39. package/dist/lib/api/openapi/openApiGenerator.d.ts +1 -1
  40. package/dist/lib/api/rateLimiter.d.ts +15 -5
  41. package/dist/lib/api/rateLimiter.js +42 -14
  42. package/dist/lib/api/request/kuzzleRequest.d.ts +83 -12
  43. package/dist/lib/api/request/kuzzleRequest.js +88 -23
  44. package/dist/lib/api/request/requestContext.d.ts +20 -5
  45. package/dist/lib/api/request/requestContext.js +14 -4
  46. package/dist/lib/api/request/requestInput.d.ts +37 -6
  47. package/dist/lib/api/request/requestInput.js +22 -9
  48. package/dist/lib/api/request/requestResponse.d.ts +45 -9
  49. package/dist/lib/api/request/requestResponse.js +34 -3
  50. package/dist/lib/cluster/command.d.ts +131 -37
  51. package/dist/lib/cluster/command.js +243 -71
  52. package/dist/lib/cluster/idCardHandler.d.ts +18 -5
  53. package/dist/lib/cluster/idCardHandler.js +52 -19
  54. package/dist/lib/cluster/index.d.ts +8 -2
  55. package/dist/lib/cluster/index.js +6 -2
  56. package/dist/lib/cluster/node.d.ts +127 -49
  57. package/dist/lib/cluster/node.js +412 -179
  58. package/dist/lib/cluster/protobuf/command.proto +18 -0
  59. package/dist/lib/cluster/protobuf/commandMessages.d.ts +104 -0
  60. package/dist/lib/cluster/protobuf/commandMessages.js +30 -0
  61. package/dist/lib/cluster/protobuf/syncMessages.d.ts +184 -0
  62. package/dist/lib/cluster/protobuf/syncMessages.js +23 -0
  63. package/dist/lib/cluster/publisher.d.ts +118 -78
  64. package/dist/lib/cluster/publisher.js +174 -72
  65. package/dist/lib/cluster/state.d.ts +15 -9
  66. package/dist/lib/cluster/state.js +12 -8
  67. package/dist/lib/cluster/subscriber.d.ts +185 -131
  68. package/dist/lib/cluster/subscriber.js +357 -95
  69. package/dist/lib/cluster/workers/IDCardRenewer.d.ts +39 -8
  70. package/dist/lib/cluster/workers/IDCardRenewer.js +88 -23
  71. package/dist/lib/config/default.config.d.ts +2 -2
  72. package/dist/lib/config/default.config.js +10 -3
  73. package/dist/lib/config/documentEventAliases.d.ts +1 -1
  74. package/dist/lib/config/index.d.ts +2 -5
  75. package/dist/lib/config/index.js +30 -17
  76. package/dist/lib/core/auth/formatProcessing.d.ts +3 -3
  77. package/dist/lib/core/auth/passportResponse.d.ts +1 -1
  78. package/dist/lib/core/auth/passportWrapper.d.ts +1 -1
  79. package/dist/lib/core/auth/passportWrapper.js +14 -13
  80. package/dist/lib/core/auth/tokenManager.d.ts +24 -3
  81. package/dist/lib/core/auth/tokenManager.js +47 -19
  82. package/dist/lib/core/backend/applicationManager.d.ts +2 -2
  83. package/dist/lib/core/backend/backend.d.ts +16 -5
  84. package/dist/lib/core/backend/backend.js +14 -6
  85. package/dist/lib/core/backend/backendCluster.d.ts +1 -1
  86. package/dist/lib/core/backend/backendConfig.d.ts +17 -5
  87. package/dist/lib/core/backend/backendConfig.js +1 -0
  88. package/dist/lib/core/backend/backendController.d.ts +1 -1
  89. package/dist/lib/core/backend/backendController.js +8 -1
  90. package/dist/lib/core/backend/backendErrors.d.ts +15 -8
  91. package/dist/lib/core/backend/backendErrors.js +5 -0
  92. package/dist/lib/core/backend/backendHook.d.ts +1 -1
  93. package/dist/lib/core/backend/backendImport.d.ts +1 -1
  94. package/dist/lib/core/backend/backendOpenApi.d.ts +3 -2
  95. package/dist/lib/core/backend/backendPipe.d.ts +1 -1
  96. package/dist/lib/core/backend/backendPipe.js +9 -1
  97. package/dist/lib/core/backend/backendPlugin.d.ts +2 -2
  98. package/dist/lib/core/backend/backendSubscription.d.ts +2 -2
  99. package/dist/lib/core/backend/backendVault.d.ts +1 -1
  100. package/dist/lib/core/backend/backendVault.js +8 -1
  101. package/dist/lib/core/cache/cacheEngine.d.ts +7 -4
  102. package/dist/lib/core/cache/cacheEngine.js +25 -8
  103. package/dist/lib/core/debug/kuzzleDebugger.d.ts +2 -1
  104. package/dist/lib/core/debug/kuzzleDebugger.js +31 -17
  105. package/dist/lib/core/network/accessLogger.d.ts +33 -18
  106. package/dist/lib/core/network/accessLogger.js +135 -73
  107. package/dist/lib/core/network/clientConnection.d.ts +13 -11
  108. package/dist/lib/core/network/clientConnection.js +33 -9
  109. package/dist/lib/core/network/context.d.ts +17 -22
  110. package/dist/lib/core/network/context.js +43 -26
  111. package/dist/lib/core/network/entryPoint.d.ts +38 -16
  112. package/dist/lib/core/network/entryPoint.js +119 -48
  113. package/dist/lib/core/network/httpRouter/index.d.ts +20 -50
  114. package/dist/lib/core/network/httpRouter/index.js +61 -75
  115. package/dist/lib/core/network/httpRouter/routeHandler.d.ts +17 -32
  116. package/dist/lib/core/network/httpRouter/routeHandler.js +26 -36
  117. package/dist/lib/core/network/httpRouter/routePart.d.ts +9 -18
  118. package/dist/lib/core/network/httpRouter/routePart.js +61 -43
  119. package/dist/lib/core/network/httpRouter/routeTypes.d.ts +3 -0
  120. package/dist/lib/core/network/httpRouter/routeTypes.js +23 -0
  121. package/dist/lib/core/network/networkEntryPoint.d.ts +20 -0
  122. package/dist/lib/core/network/networkEntryPoint.js +23 -0
  123. package/dist/lib/core/network/protocolManifest.d.ts +5 -4
  124. package/dist/lib/core/network/protocolManifest.js +6 -3
  125. package/dist/lib/core/network/protocols/httpMessage.d.ts +25 -18
  126. package/dist/lib/core/network/protocols/httpMessage.js +14 -11
  127. package/dist/lib/core/network/protocols/httpwsProtocol.d.ts +84 -93
  128. package/dist/lib/core/network/protocols/httpwsProtocol.js +284 -129
  129. package/dist/lib/core/network/protocols/internalProtocol.d.ts +26 -15
  130. package/dist/lib/core/network/protocols/internalProtocol.js +17 -16
  131. package/dist/lib/core/network/protocols/mqttProtocol.d.ts +56 -32
  132. package/dist/lib/core/network/protocols/mqttProtocol.js +91 -44
  133. package/dist/lib/core/network/protocols/protocol.d.ts +85 -21
  134. package/dist/lib/core/network/protocols/protocol.js +83 -27
  135. package/dist/lib/core/network/router.d.ts +13 -22
  136. package/dist/lib/core/network/router.js +59 -46
  137. package/dist/lib/core/plugin/plugin.d.ts +57 -51
  138. package/dist/lib/core/plugin/plugin.js +218 -103
  139. package/dist/lib/core/plugin/pluginContext.d.ts +54 -11
  140. package/dist/lib/core/plugin/pluginContext.js +99 -58
  141. package/dist/lib/core/plugin/pluginManifest.d.ts +6 -2
  142. package/dist/lib/core/plugin/pluginManifest.js +18 -11
  143. package/dist/lib/core/plugin/pluginRepository.d.ts +35 -44
  144. package/dist/lib/core/plugin/pluginRepository.js +35 -50
  145. package/dist/lib/core/plugin/pluginsManager.d.ts +128 -46
  146. package/dist/lib/core/plugin/pluginsManager.js +468 -231
  147. package/dist/lib/core/plugin/privilegedContext.d.ts +4 -9
  148. package/dist/lib/core/plugin/privilegedContext.js +5 -10
  149. package/dist/lib/core/realtime/actionEnum.d.ts +12 -21
  150. package/dist/lib/core/realtime/actionEnum.js +6 -7
  151. package/dist/lib/core/realtime/channel.d.ts +11 -5
  152. package/dist/lib/core/realtime/channel.js +17 -2
  153. package/dist/lib/core/realtime/connectionRooms.d.ts +2 -2
  154. package/dist/lib/core/realtime/hotelClerk.d.ts +12 -6
  155. package/dist/lib/core/realtime/hotelClerk.js +29 -11
  156. package/dist/lib/core/realtime/index.d.ts +8 -3
  157. package/dist/lib/core/realtime/index.js +12 -5
  158. package/dist/lib/core/realtime/notification/document.d.ts +54 -25
  159. package/dist/lib/core/realtime/notification/document.js +10 -13
  160. package/dist/lib/core/realtime/notification/index.d.ts +9 -3
  161. package/dist/lib/core/realtime/notification/index.js +10 -4
  162. package/dist/lib/core/realtime/notification/server.d.ts +7 -10
  163. package/dist/lib/core/realtime/notification/server.js +4 -7
  164. package/dist/lib/core/realtime/notification/user.d.ts +45 -21
  165. package/dist/lib/core/realtime/notification/user.js +8 -9
  166. package/dist/lib/core/realtime/notifier.d.ts +52 -40
  167. package/dist/lib/core/realtime/notifier.js +60 -25
  168. package/dist/lib/core/realtime/room.d.ts +1 -1
  169. package/dist/lib/core/realtime/subscription.d.ts +11 -6
  170. package/dist/lib/core/realtime/subscription.js +5 -1
  171. package/dist/lib/core/security/index.d.ts +14 -6
  172. package/dist/lib/core/security/index.js +27 -13
  173. package/dist/lib/core/security/profileRepository.d.ts +24 -19
  174. package/dist/lib/core/security/profileRepository.js +23 -10
  175. package/dist/lib/core/security/roleRepository.d.ts +60 -23
  176. package/dist/lib/core/security/roleRepository.js +122 -53
  177. package/dist/lib/core/security/securityLoader.d.ts +33 -18
  178. package/dist/lib/core/security/securityLoader.js +43 -16
  179. package/dist/lib/core/security/tokenRepository.d.ts +21 -7
  180. package/dist/lib/core/security/tokenRepository.js +50 -23
  181. package/dist/lib/core/security/userRepository.d.ts +44 -21
  182. package/dist/lib/core/security/userRepository.js +59 -19
  183. package/dist/lib/core/shared/KoncordeWrapper.d.ts +1 -1
  184. package/dist/lib/core/shared/ObjectRepository.d.ts +80 -18
  185. package/dist/lib/core/shared/ObjectRepository.js +57 -29
  186. package/dist/lib/core/shared/abstractManifest.d.ts +21 -8
  187. package/dist/lib/core/shared/abstractManifest.js +57 -17
  188. package/dist/lib/core/shared/sdk/embeddedSdk.d.ts +3 -1
  189. package/dist/lib/core/shared/sdk/embeddedSdk.js +8 -7
  190. package/dist/lib/core/shared/sdk/funnelProtocol.d.ts +2 -1
  191. package/dist/lib/core/shared/sdk/funnelProtocol.js +12 -3
  192. package/dist/lib/core/shared/sdk/impersonatedSdk.d.ts +11 -5
  193. package/dist/lib/core/shared/sdk/impersonatedSdk.js +22 -9
  194. package/dist/lib/core/shared/store.d.ts +45 -29
  195. package/dist/lib/core/shared/store.js +48 -27
  196. package/dist/lib/core/statistics/statistics.d.ts +1 -1
  197. package/dist/lib/core/storage/clientAdapter.d.ts +39 -21
  198. package/dist/lib/core/storage/clientAdapter.js +88 -48
  199. package/dist/lib/core/storage/indexCache.d.ts +8 -0
  200. package/dist/lib/core/storage/indexCache.js +16 -7
  201. package/dist/lib/core/storage/storageEngine.d.ts +7 -6
  202. package/dist/lib/core/storage/storageEngine.js +11 -8
  203. package/dist/lib/core/validation/baseType.d.ts +22 -22
  204. package/dist/lib/core/validation/baseType.js +11 -26
  205. package/dist/lib/core/validation/specification.d.ts +148 -0
  206. package/dist/lib/core/validation/specification.js +34 -0
  207. package/dist/lib/core/validation/typeOptions.d.ts +62 -0
  208. package/dist/lib/core/validation/typeOptions.js +23 -0
  209. package/dist/lib/core/validation/types/anything.d.ts +3 -6
  210. package/dist/lib/core/validation/types/anything.js +7 -7
  211. package/dist/lib/core/validation/types/boolean.d.ts +5 -12
  212. package/dist/lib/core/validation/types/boolean.js +7 -12
  213. package/dist/lib/core/validation/types/date.d.ts +19 -11
  214. package/dist/lib/core/validation/types/date.js +212 -161
  215. package/dist/lib/core/validation/types/email.d.ts +7 -11
  216. package/dist/lib/core/validation/types/email.js +13 -17
  217. package/dist/lib/core/validation/types/enum.d.ts +7 -11
  218. package/dist/lib/core/validation/types/enum.js +39 -20
  219. package/dist/lib/core/validation/types/geoPoint.d.ts +5 -13
  220. package/dist/lib/core/validation/types/geoPoint.js +10 -15
  221. package/dist/lib/core/validation/types/geoShape.d.ts +22 -21
  222. package/dist/lib/core/validation/types/geoShape.js +113 -129
  223. package/dist/lib/core/validation/types/geoShapeUtils.d.ts +15 -0
  224. package/dist/lib/core/validation/types/geoShapeUtils.js +75 -0
  225. package/dist/lib/core/validation/types/integer.d.ts +7 -5
  226. package/dist/lib/core/validation/types/integer.js +7 -13
  227. package/dist/lib/core/validation/types/ipAddress.d.ts +7 -11
  228. package/dist/lib/core/validation/types/ipAddress.js +13 -17
  229. package/dist/lib/core/validation/types/numeric.d.ts +7 -11
  230. package/dist/lib/core/validation/types/numeric.js +22 -29
  231. package/dist/lib/core/validation/types/object.d.ts +8 -15
  232. package/dist/lib/core/validation/types/object.js +12 -21
  233. package/dist/lib/core/validation/types/string.d.ts +7 -11
  234. package/dist/lib/core/validation/types/string.js +22 -29
  235. package/dist/lib/core/validation/types/url.d.ts +7 -11
  236. package/dist/lib/core/validation/types/url.js +14 -18
  237. package/dist/lib/core/validation/validation.d.ts +119 -80
  238. package/dist/lib/core/validation/validation.js +470 -412
  239. package/dist/lib/core/validation/validationUtils.d.ts +31 -0
  240. package/dist/lib/core/validation/validationUtils.js +190 -0
  241. package/dist/lib/kerror/codes/4-plugin.json +0 -12
  242. package/dist/lib/kerror/codes/index.d.ts +12 -2
  243. package/dist/lib/kerror/codes/index.js +5 -4
  244. package/dist/lib/kerror/errors/badRequestError.d.ts +1 -1
  245. package/dist/lib/kerror/errors/badRequestError.js +1 -1
  246. package/dist/lib/kerror/errors/externalServiceError.d.ts +1 -1
  247. package/dist/lib/kerror/errors/externalServiceError.js +1 -1
  248. package/dist/lib/kerror/errors/forbiddenError.d.ts +1 -1
  249. package/dist/lib/kerror/errors/forbiddenError.js +1 -1
  250. package/dist/lib/kerror/errors/gatewayTimeoutError.d.ts +1 -1
  251. package/dist/lib/kerror/errors/gatewayTimeoutError.js +1 -1
  252. package/dist/lib/kerror/errors/internalError.d.ts +1 -1
  253. package/dist/lib/kerror/errors/internalError.js +1 -1
  254. package/dist/lib/kerror/errors/kuzzleError.d.ts +32 -3
  255. package/dist/lib/kerror/errors/kuzzleError.js +21 -7
  256. package/dist/lib/kerror/errors/multipleErrorsError.d.ts +2 -2
  257. package/dist/lib/kerror/errors/multipleErrorsError.js +2 -2
  258. package/dist/lib/kerror/errors/notFoundError.d.ts +1 -1
  259. package/dist/lib/kerror/errors/notFoundError.js +1 -1
  260. package/dist/lib/kerror/errors/partialError.d.ts +8 -2
  261. package/dist/lib/kerror/errors/partialError.js +22 -9
  262. package/dist/lib/kerror/errors/pluginImplementationError.d.ts +9 -1
  263. package/dist/lib/kerror/errors/pluginImplementationError.js +9 -3
  264. package/dist/lib/kerror/errors/preconditionError.d.ts +1 -1
  265. package/dist/lib/kerror/errors/preconditionError.js +1 -1
  266. package/dist/lib/kerror/errors/serviceUnavailableError.d.ts +1 -1
  267. package/dist/lib/kerror/errors/serviceUnavailableError.js +1 -1
  268. package/dist/lib/kerror/errors/sizeLimitError.d.ts +1 -1
  269. package/dist/lib/kerror/errors/sizeLimitError.js +1 -1
  270. package/dist/lib/kerror/errors/tooManyRequestsError.d.ts +1 -1
  271. package/dist/lib/kerror/errors/tooManyRequestsError.js +1 -1
  272. package/dist/lib/kerror/errors/unauthorizedError.d.ts +1 -1
  273. package/dist/lib/kerror/errors/unauthorizedError.js +1 -1
  274. package/dist/lib/kerror/index.d.ts +19 -13
  275. package/dist/lib/kerror/index.js +60 -19
  276. package/dist/lib/kuzzle/Logger.d.ts +2 -2
  277. package/dist/lib/kuzzle/dumpGenerator.d.ts +12 -8
  278. package/dist/lib/kuzzle/dumpGenerator.js +130 -62
  279. package/dist/lib/kuzzle/event/KuzzleEventEmitter.d.ts +18 -9
  280. package/dist/lib/kuzzle/event/KuzzleEventEmitter.js +45 -18
  281. package/dist/lib/kuzzle/event/pipeRunner.d.ts +37 -16
  282. package/dist/lib/kuzzle/event/pipeRunner.js +73 -26
  283. package/dist/lib/kuzzle/event/waterfall.d.ts +11 -1
  284. package/dist/lib/kuzzle/event/waterfall.js +38 -13
  285. package/dist/lib/kuzzle/internalIndexHandler.d.ts +11 -174
  286. package/dist/lib/kuzzle/internalIndexHandler.js +58 -29
  287. package/dist/lib/kuzzle/kuzzle.d.ts +25 -10
  288. package/dist/lib/kuzzle/kuzzle.js +74 -17
  289. package/dist/lib/kuzzle/kuzzleStateEnum.d.ts +16 -12
  290. package/dist/lib/kuzzle/kuzzleStateEnum.js +5 -7
  291. package/dist/lib/kuzzle/vault.d.ts +5 -1
  292. package/dist/lib/kuzzle/vault.js +29 -17
  293. package/dist/lib/model/security/profile.d.ts +34 -5
  294. package/dist/lib/model/security/profile.js +6 -5
  295. package/dist/lib/model/security/rights.d.ts +12 -4
  296. package/dist/lib/model/security/rights.js +7 -6
  297. package/dist/lib/model/security/role.d.ts +8 -4
  298. package/dist/lib/model/security/role.js +12 -6
  299. package/dist/lib/model/security/token.d.ts +8 -0
  300. package/dist/lib/model/security/user.d.ts +8 -2
  301. package/dist/lib/model/security/user.js +7 -4
  302. package/dist/lib/model/storage/apiKey.d.ts +55 -26
  303. package/dist/lib/model/storage/apiKey.js +97 -24
  304. package/dist/lib/model/storage/baseModel.d.ts +77 -66
  305. package/dist/lib/model/storage/baseModel.js +21 -34
  306. package/dist/lib/service/cache/redis.d.ts +53 -36
  307. package/dist/lib/service/cache/redis.js +148 -71
  308. package/dist/lib/service/service.d.ts +14 -19
  309. package/dist/lib/service/service.js +41 -22
  310. package/dist/lib/service/storage/7/elasticsearch.d.ts +136 -93
  311. package/dist/lib/service/storage/7/elasticsearch.js +218 -165
  312. package/dist/lib/service/storage/7/esWrapper.d.ts +30 -13
  313. package/dist/lib/service/storage/7/esWrapper.js +58 -37
  314. package/dist/lib/service/storage/8/elasticsearch.d.ts +153 -119
  315. package/dist/lib/service/storage/8/elasticsearch.js +286 -213
  316. package/dist/lib/service/storage/8/esWrapper.d.ts +30 -13
  317. package/dist/lib/service/storage/8/esWrapper.js +59 -38
  318. package/dist/lib/service/storage/commons/queryTranslator.d.ts +3 -3
  319. package/dist/lib/service/storage/commons/queryTranslator.js +71 -35
  320. package/dist/lib/types/ApiRoute.d.ts +12 -0
  321. package/dist/lib/types/ApiRoute.js +23 -0
  322. package/dist/lib/types/ClientConnection.d.ts +1 -1
  323. package/dist/lib/types/EventHandler.d.ts +10 -0
  324. package/dist/lib/types/Global.d.ts +8 -3
  325. package/dist/lib/types/HttpMessage.d.ts +2 -2
  326. package/dist/lib/types/HttpStream.d.ts +1 -1
  327. package/dist/lib/types/HttpStream.js +3 -1
  328. package/dist/lib/types/JSONObject.d.ts +9 -0
  329. package/dist/lib/types/JSONObject.js +23 -0
  330. package/dist/lib/types/Kuzzle.d.ts +5 -3
  331. package/dist/lib/types/KuzzleDocument.d.ts +1 -1
  332. package/dist/lib/types/KuzzleWebSocket.d.ts +24 -0
  333. package/dist/lib/types/KuzzleWebSocket.js +23 -0
  334. package/dist/lib/types/OpenApiDefinition.d.ts +1 -1
  335. package/dist/lib/types/Plugin.d.ts +33 -8
  336. package/dist/lib/types/PluginInstance.d.ts +67 -0
  337. package/dist/lib/types/PluginInstance.js +23 -0
  338. package/dist/lib/types/Policy.d.ts +1 -1
  339. package/dist/lib/types/Target.d.ts +8 -0
  340. package/dist/lib/types/Token.d.ts +14 -2
  341. package/dist/lib/types/config/HttpConfiguration.d.ts +5 -0
  342. package/dist/lib/types/config/KuzzleConfiguration.d.ts +102 -1
  343. package/dist/lib/types/config/PluginsConfiguration.d.ts +3 -2
  344. package/dist/lib/types/config/SecurityConfiguration.d.ts +6 -2
  345. package/dist/lib/types/config/ServerConfiguration.d.ts +2 -2
  346. package/dist/lib/types/config/ServicesConfiguration.d.ts +1 -1
  347. package/dist/lib/types/config/cache/BaseCacheRedisConfiguration.d.ts +131 -0
  348. package/dist/lib/types/config/cache/BaseCacheRedisConfiguration.js +3 -0
  349. package/dist/lib/types/config/internalCache/InternalCacheRedisConfiguration.d.ts +2 -106
  350. package/dist/lib/types/config/publicCache/PublicCacheRedisConfiguration.d.ts +2 -26
  351. package/dist/lib/types/config/storageEngine/StorageEngineElasticsearchConfiguration.d.ts +3 -0
  352. package/dist/lib/types/controllers/Controller.d.ts +12 -3
  353. package/dist/lib/types/controllers/ControllerDefinition.d.ts +2 -2
  354. package/dist/lib/types/controllers/{adminControlller.type.js → adminController.type.js} +1 -1
  355. package/dist/lib/types/controllers/authController.type.d.ts +2 -2
  356. package/dist/lib/types/core/auth/formatProcessing.type.d.ts +7 -1
  357. package/dist/lib/types/errors/ErrorDomains.d.ts +1 -1
  358. package/dist/lib/types/events/EventGenericDocument.d.ts +10 -9
  359. package/dist/lib/types/events/EventProtocol.d.ts +4 -4
  360. package/dist/lib/types/index.d.ts +7 -0
  361. package/dist/lib/types/index.js +7 -0
  362. package/dist/lib/types/shared/StoreCollectionsDefinition.d.ts +1 -1
  363. package/dist/lib/types/storage/7/Elasticsearch.d.ts +62 -13
  364. package/dist/lib/types/storage/8/Elasticsearch.d.ts +62 -13
  365. package/dist/lib/util/Inflector.d.ts +4 -1
  366. package/dist/lib/util/Inflector.js +0 -3
  367. package/dist/lib/util/assertType.d.ts +24 -27
  368. package/dist/lib/util/assertType.js +28 -39
  369. package/dist/lib/util/async.js +19 -6
  370. package/dist/lib/util/asyncStore.js +1 -1
  371. package/dist/lib/util/bufferedPassThrough.d.ts +9 -0
  372. package/dist/lib/util/bufferedPassThrough.js +27 -13
  373. package/dist/lib/util/bytes.d.ts +1 -1
  374. package/dist/lib/util/bytes.js +6 -2
  375. package/dist/lib/util/debug.d.ts +3 -1
  376. package/dist/lib/util/debug.js +42 -10
  377. package/dist/lib/util/deprecate.d.ts +9 -1
  378. package/dist/lib/util/deprecate.js +10 -6
  379. package/dist/lib/util/didYouMean.d.ts +2 -1
  380. package/dist/lib/util/didYouMean.js +8 -4
  381. package/dist/lib/util/distributedLock.d.ts +56 -0
  382. package/dist/lib/util/distributedLock.js +166 -0
  383. package/dist/lib/util/dump-collection.d.ts +1 -1
  384. package/dist/lib/util/dump-collection.js +4 -5
  385. package/dist/lib/util/extractFields.d.ts +15 -11
  386. package/dist/lib/util/extractFields.js +8 -9
  387. package/dist/lib/util/koncordeCompat.d.ts +2 -2
  388. package/dist/lib/util/koncordeCompat.js +33 -0
  389. package/dist/lib/util/memoize.d.ts +7 -6
  390. package/dist/lib/util/memoize.js +3 -3
  391. package/dist/lib/util/mutex.d.ts +22 -2
  392. package/dist/lib/util/mutex.js +39 -1
  393. package/dist/lib/util/name-generator.js +14 -2
  394. package/dist/lib/util/promback.d.ts +20 -11
  395. package/dist/lib/util/promback.js +14 -7
  396. package/dist/lib/util/requestAssertions.d.ts +30 -10
  397. package/dist/lib/util/requestAssertions.js +125 -121
  398. package/dist/lib/util/safeObject.d.ts +3 -3
  399. package/dist/lib/util/safeObject.js +7 -3
  400. package/dist/lib/util/stackTrace.d.ts +13 -5
  401. package/dist/lib/util/stackTrace.js +17 -12
  402. package/dist/lib/util/thrown.d.ts +13 -0
  403. package/dist/lib/util/thrown.js +46 -0
  404. package/dist/package.json +26 -19
  405. package/package.json +26 -19
  406. package/dist/lib/util/wildcard.d.ts +0 -1
  407. package/dist/lib/util/wildcard.js +0 -46
  408. /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
@@ -1,4 +1,4 @@
1
- import { JSONObject } from "kuzzle-sdk";
1
+ import type { JSONObject } from "../types/JSONObject";
2
2
  import { HttpStream } from "../types";
3
3
  /**
4
4
  * Flatten an object transform:
@@ -58,10 +58,7 @@ function flattenObject(target) {
58
58
  }
59
59
  exports.flattenObject = flattenObject;
60
60
  function flattenStep(output, object, prev = null) {
61
- const keys = Object.keys(object);
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.toString());
199
+ this.writeStream.write(String(e));
201
200
  }
202
201
  this.writeStream.end();
203
202
  return waitWrite;
@@ -1,17 +1,21 @@
1
- export = extractFields;
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 {Object} document - Document to extract fields from
7
- * @param {Object} options - alsoExtractValues (false), fieldsToIgnore ( [ ] )
9
+ * @param document - Document to extract fields from
10
+ * @param options - alsoExtractValues (false), fieldsToIgnore ( [ ] )
8
11
  *
9
- * @returns { Array<String> | Array<{ key: String, value: any }> }
12
+ * @returns Array of field paths, or of { key, value } pairs when alsoExtractValues is true
10
13
  */
11
- declare function extractFields(document: any, { fieldsToIgnore, alsoExtractValues }?: any, { path, extractedFields }?: {
12
- path?: any;
13
- extractedFields?: any[];
14
- }): Array<string> | Array<{
15
- key: string;
16
- value: any;
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
- "use strict";
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 {Object} document - Document to extract fields from
28
- * @param {Object} options - alsoExtractValues (false), fieldsToIgnore ( [ ] )
27
+ * @param document - Document to extract fields from
28
+ * @param options - alsoExtractValues (false), fieldsToIgnore ( [ ] )
29
29
  *
30
- * @returns { Array<String> | Array<{ key: String, value: any }> }
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.length &&
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 "kuzzle-sdk";
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
- };
@@ -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;
@@ -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
  }
@@ -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 = true;
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 names[randomNumber(names.length)];
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 adjectives[randomNumber(adjectives.length)];
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
- export = Promback;
2
- declare class Promback {
3
- constructor(callback?: any);
4
- _callback: any;
5
- _resolve: (thenableOrResult?: any) => void;
6
- _reject: (error?: any) => void;
7
- deferred: Bluebird<any>;
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
- resolve(result: any): Bluebird<any>;
10
- reject(error: any): Bluebird<any>;
11
- get promise(): Bluebird<any>;
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
- import Bluebird = require("bluebird");
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
- "use strict";
22
- const Bluebird = require("bluebird");
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 Bluebird((res, rej) => {
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
- if (this.isPromise) {
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.isPromise) {
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
  }