kuzzle 2.19.2 → 2.19.3

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 (289) hide show
  1. package/lib/api/controllers/adminController.js +94 -80
  2. package/lib/api/controllers/authController.js +239 -212
  3. package/lib/api/controllers/baseController.js +89 -51
  4. package/lib/api/controllers/bulkController.js +62 -49
  5. package/lib/api/controllers/clusterController.js +6 -8
  6. package/lib/api/controllers/collectionController.js +140 -129
  7. package/lib/api/controllers/debugController.d.ts +2 -2
  8. package/lib/api/controllers/debugController.js +33 -31
  9. package/lib/api/controllers/documentController.js +365 -274
  10. package/lib/api/controllers/index.js +13 -13
  11. package/lib/api/controllers/indexController.js +46 -50
  12. package/lib/api/controllers/memoryStorageController.js +410 -360
  13. package/lib/api/controllers/realtimeController.js +37 -36
  14. package/lib/api/controllers/securityController.js +553 -412
  15. package/lib/api/controllers/serverController.js +111 -104
  16. package/lib/api/documentExtractor.js +75 -68
  17. package/lib/api/funnel.js +411 -312
  18. package/lib/api/httpRoutes.js +1493 -324
  19. package/lib/api/openapi/OpenApiManager.d.ts +1 -1
  20. package/lib/api/openapi/OpenApiManager.js +22 -22
  21. package/lib/api/openapi/components/document/count.yaml +1 -1
  22. package/lib/api/openapi/components/document/create.yaml +2 -2
  23. package/lib/api/openapi/components/document/delete.yaml +1 -1
  24. package/lib/api/openapi/components/document/deleteByQuery.yaml +1 -1
  25. package/lib/api/openapi/components/document/exists.yaml +1 -1
  26. package/lib/api/openapi/components/document/get.yaml +2 -2
  27. package/lib/api/openapi/components/document/index.js +12 -12
  28. package/lib/api/openapi/components/document/replace.yaml +1 -1
  29. package/lib/api/openapi/components/document/scroll.yaml +1 -1
  30. package/lib/api/openapi/components/document/validate.yaml +1 -1
  31. package/lib/api/openapi/components/index.d.ts +2 -2
  32. package/lib/api/openapi/components/index.js +1 -1
  33. package/lib/api/openapi/components/security/index.js +1 -1
  34. package/lib/api/openapi/components/security/upsertUser.yaml +2 -3
  35. package/lib/api/openapi/index.d.ts +1 -1
  36. package/lib/api/openapi/openApiGenerator.d.ts +1 -1
  37. package/lib/api/openapi/openApiGenerator.js +7 -7
  38. package/lib/api/rateLimiter.js +12 -13
  39. package/lib/api/request/index.d.ts +4 -4
  40. package/lib/api/request/kuzzleRequest.d.ts +9 -9
  41. package/lib/api/request/kuzzleRequest.js +89 -87
  42. package/lib/api/request/requestContext.d.ts +2 -2
  43. package/lib/api/request/requestContext.js +17 -17
  44. package/lib/api/request/requestInput.d.ts +1 -1
  45. package/lib/api/request/requestInput.js +19 -19
  46. package/lib/api/request/requestResponse.d.ts +4 -4
  47. package/lib/api/request/requestResponse.js +31 -33
  48. package/lib/cluster/command.js +48 -44
  49. package/lib/cluster/idCardHandler.d.ts +1 -1
  50. package/lib/cluster/idCardHandler.js +15 -15
  51. package/lib/cluster/index.js +2 -2
  52. package/lib/cluster/node.js +301 -269
  53. package/lib/cluster/publisher.js +45 -46
  54. package/lib/cluster/state.d.ts +5 -5
  55. package/lib/cluster/state.js +8 -8
  56. package/lib/cluster/subscriber.js +163 -113
  57. package/lib/cluster/workers/IDCardRenewer.js +33 -32
  58. package/lib/config/default.config.d.ts +1 -1
  59. package/lib/config/default.config.js +212 -171
  60. package/lib/config/documentEventAliases.js +6 -6
  61. package/lib/config/index.js +161 -98
  62. package/lib/config/sdkCompatibility.json +8 -8
  63. package/lib/core/auth/formatProcessing.js +7 -7
  64. package/lib/core/auth/passportResponse.js +7 -7
  65. package/lib/core/auth/passportWrapper.js +34 -30
  66. package/lib/core/auth/tokenManager.d.ts +2 -2
  67. package/lib/core/auth/tokenManager.js +11 -10
  68. package/lib/core/backend/applicationManager.d.ts +1 -1
  69. package/lib/core/backend/applicationManager.js +2 -2
  70. package/lib/core/backend/backend.d.ts +3 -3
  71. package/lib/core/backend/backend.js +34 -31
  72. package/lib/core/backend/backendCluster.d.ts +2 -2
  73. package/lib/core/backend/backendCluster.js +5 -5
  74. package/lib/core/backend/backendConfig.d.ts +2 -2
  75. package/lib/core/backend/backendConfig.js +3 -3
  76. package/lib/core/backend/backendController.d.ts +2 -2
  77. package/lib/core/backend/backendController.js +9 -10
  78. package/lib/core/backend/backendErrors.d.ts +3 -3
  79. package/lib/core/backend/backendErrors.js +2 -1
  80. package/lib/core/backend/backendHook.d.ts +2 -2
  81. package/lib/core/backend/backendHook.js +5 -5
  82. package/lib/core/backend/backendImport.d.ts +3 -3
  83. package/lib/core/backend/backendImport.js +23 -23
  84. package/lib/core/backend/backendOpenApi.d.ts +2 -2
  85. package/lib/core/backend/backendOpenApi.js +16 -16
  86. package/lib/core/backend/backendPipe.d.ts +2 -2
  87. package/lib/core/backend/backendPipe.js +6 -6
  88. package/lib/core/backend/backendPlugin.d.ts +4 -4
  89. package/lib/core/backend/backendPlugin.js +14 -14
  90. package/lib/core/backend/backendStorage.d.ts +2 -2
  91. package/lib/core/backend/backendStorage.js +1 -2
  92. package/lib/core/backend/backendVault.d.ts +2 -2
  93. package/lib/core/backend/backendVault.js +3 -3
  94. package/lib/core/backend/index.d.ts +14 -14
  95. package/lib/core/backend/internalLogger.d.ts +1 -1
  96. package/lib/core/backend/internalLogger.js +5 -5
  97. package/lib/core/cache/cacheDbEnum.js +4 -4
  98. package/lib/core/cache/cacheEngine.js +79 -85
  99. package/lib/core/network/accessLogger.js +126 -120
  100. package/lib/core/network/clientConnection.js +5 -5
  101. package/lib/core/network/context.js +8 -8
  102. package/lib/core/network/entryPoint.js +100 -85
  103. package/lib/core/network/httpRouter/index.js +63 -60
  104. package/lib/core/network/httpRouter/routeHandler.js +18 -19
  105. package/lib/core/network/httpRouter/routePart.js +23 -19
  106. package/lib/core/network/protocolManifest.js +3 -3
  107. package/lib/core/network/protocols/httpMessage.js +8 -10
  108. package/lib/core/network/protocols/httpwsProtocol.js +305 -250
  109. package/lib/core/network/protocols/internalProtocol.js +27 -24
  110. package/lib/core/network/protocols/mqttProtocol.js +106 -96
  111. package/lib/core/network/protocols/protocol.js +20 -17
  112. package/lib/core/network/router.js +56 -46
  113. package/lib/core/plugin/plugin.js +151 -120
  114. package/lib/core/plugin/pluginContext.d.ts +7 -7
  115. package/lib/core/plugin/pluginContext.js +48 -44
  116. package/lib/core/plugin/pluginManifest.js +13 -12
  117. package/lib/core/plugin/pluginRepository.js +26 -27
  118. package/lib/core/plugin/pluginsManager.js +425 -304
  119. package/lib/core/plugin/privilegedContext.js +3 -3
  120. package/lib/core/realtime/actionEnum.js +1 -1
  121. package/lib/core/realtime/channel.d.ts +1 -1
  122. package/lib/core/realtime/channel.js +22 -22
  123. package/lib/core/realtime/connectionRooms.d.ts +1 -1
  124. package/lib/core/realtime/hotelClerk.d.ts +2 -2
  125. package/lib/core/realtime/hotelClerk.js +53 -50
  126. package/lib/core/realtime/index.js +5 -5
  127. package/lib/core/realtime/notification/document.js +25 -25
  128. package/lib/core/realtime/notification/index.js +4 -4
  129. package/lib/core/realtime/notification/server.js +3 -3
  130. package/lib/core/realtime/notification/user.js +4 -4
  131. package/lib/core/realtime/notifier.js +113 -75
  132. package/lib/core/realtime/room.d.ts +1 -1
  133. package/lib/core/realtime/subscription.d.ts +1 -1
  134. package/lib/core/realtime/subscription.js +1 -1
  135. package/lib/core/security/index.js +8 -8
  136. package/lib/core/security/profileRepository.d.ts +6 -6
  137. package/lib/core/security/profileRepository.js +48 -45
  138. package/lib/core/security/roleRepository.js +127 -115
  139. package/lib/core/security/securityLoader.js +70 -63
  140. package/lib/core/security/tokenRepository.js +132 -118
  141. package/lib/core/security/userRepository.js +104 -88
  142. package/lib/core/shared/KoncordeWrapper.d.ts +1 -1
  143. package/lib/core/shared/KoncordeWrapper.js +3 -1
  144. package/lib/core/shared/abstractManifest.js +22 -23
  145. package/lib/core/shared/repository.js +69 -67
  146. package/lib/core/shared/sdk/embeddedSdk.d.ts +2 -2
  147. package/lib/core/shared/sdk/embeddedSdk.js +36 -32
  148. package/lib/core/shared/sdk/funnelProtocol.d.ts +1 -1
  149. package/lib/core/shared/sdk/funnelProtocol.js +11 -11
  150. package/lib/core/shared/sdk/impersonatedSdk.js +19 -18
  151. package/lib/core/shared/store.js +127 -32
  152. package/lib/core/statistics/index.js +2 -2
  153. package/lib/core/statistics/statistics.js +99 -85
  154. package/lib/core/storage/clientAdapter.js +219 -136
  155. package/lib/core/storage/indexCache.js +3 -3
  156. package/lib/core/storage/storageEngine.js +10 -13
  157. package/lib/core/storage/storeScopeEnum.js +3 -3
  158. package/lib/core/validation/baseType.js +12 -10
  159. package/lib/core/validation/index.js +2 -2
  160. package/lib/core/validation/types/anything.js +4 -4
  161. package/lib/core/validation/types/boolean.js +7 -7
  162. package/lib/core/validation/types/date.js +165 -131
  163. package/lib/core/validation/types/email.js +18 -21
  164. package/lib/core/validation/types/enum.js +34 -21
  165. package/lib/core/validation/types/geoPoint.js +7 -7
  166. package/lib/core/validation/types/geoShape.js +148 -125
  167. package/lib/core/validation/types/integer.js +9 -9
  168. package/lib/core/validation/types/ipAddress.js +17 -19
  169. package/lib/core/validation/types/numeric.js +36 -29
  170. package/lib/core/validation/types/object.js +19 -19
  171. package/lib/core/validation/types/string.js +36 -29
  172. package/lib/core/validation/types/url.js +17 -19
  173. package/lib/core/validation/validation.js +422 -378
  174. package/lib/kerror/codes/1-services.json +7 -1
  175. package/lib/kerror/codes/4-plugin.json +2 -2
  176. package/lib/kerror/codes/index.js +85 -63
  177. package/lib/kerror/errors/badRequestError.d.ts +1 -1
  178. package/lib/kerror/errors/externalServiceError.d.ts +1 -1
  179. package/lib/kerror/errors/forbiddenError.d.ts +1 -1
  180. package/lib/kerror/errors/gatewayTimeoutError.d.ts +1 -1
  181. package/lib/kerror/errors/index.d.ts +15 -15
  182. package/lib/kerror/errors/internalError.d.ts +1 -1
  183. package/lib/kerror/errors/kuzzleError.d.ts +1 -1
  184. package/lib/kerror/errors/multipleErrorsError.d.ts +1 -1
  185. package/lib/kerror/errors/multipleErrorsError.js +1 -1
  186. package/lib/kerror/errors/notFoundError.d.ts +1 -1
  187. package/lib/kerror/errors/partialError.d.ts +1 -1
  188. package/lib/kerror/errors/partialError.js +1 -1
  189. package/lib/kerror/errors/pluginImplementationError.d.ts +1 -1
  190. package/lib/kerror/errors/pluginImplementationError.js +2 -1
  191. package/lib/kerror/errors/preconditionError.d.ts +1 -1
  192. package/lib/kerror/errors/serviceUnavailableError.d.ts +1 -1
  193. package/lib/kerror/errors/sizeLimitError.d.ts +1 -1
  194. package/lib/kerror/errors/tooManyRequestsError.d.ts +1 -1
  195. package/lib/kerror/errors/unauthorizedError.d.ts +1 -1
  196. package/lib/kerror/index.d.ts +3 -3
  197. package/lib/kerror/index.js +17 -16
  198. package/lib/kuzzle/dumpGenerator.js +130 -114
  199. package/lib/kuzzle/event/kuzzleEventEmitter.js +96 -70
  200. package/lib/kuzzle/event/pipeRunner.js +25 -24
  201. package/lib/kuzzle/event/waterfall.js +13 -15
  202. package/lib/kuzzle/index.js +2 -2
  203. package/lib/kuzzle/internalIndexHandler.js +80 -59
  204. package/lib/kuzzle/kuzzle.js +99 -99
  205. package/lib/kuzzle/kuzzleStateEnum.js +1 -1
  206. package/lib/kuzzle/log.js +23 -18
  207. package/lib/kuzzle/vault.js +34 -19
  208. package/lib/model/security/profile.d.ts +3 -3
  209. package/lib/model/security/profile.js +38 -37
  210. package/lib/model/security/rights.js +5 -5
  211. package/lib/model/security/role.d.ts +3 -3
  212. package/lib/model/security/role.js +25 -26
  213. package/lib/model/security/token.d.ts +1 -1
  214. package/lib/model/security/token.js +4 -4
  215. package/lib/model/security/user.d.ts +2 -2
  216. package/lib/model/security/user.js +9 -9
  217. package/lib/model/storage/apiKey.js +43 -33
  218. package/lib/model/storage/baseModel.js +49 -45
  219. package/lib/service/cache/redis.js +60 -55
  220. package/lib/service/service.js +17 -17
  221. package/lib/service/storage/elasticsearch.js +839 -755
  222. package/lib/service/storage/esWrapper.js +103 -86
  223. package/lib/service/storage/queryTranslator.js +52 -59
  224. package/lib/types/Controller.d.ts +3 -3
  225. package/lib/types/ControllerDefinition.d.ts +3 -3
  226. package/lib/types/DebugModule.d.ts +2 -2
  227. package/lib/types/DebugModule.js +1 -1
  228. package/lib/types/Global.d.ts +1 -1
  229. package/lib/types/HttpStream.d.ts +2 -1
  230. package/lib/types/HttpStream.js +7 -5
  231. package/lib/types/Kuzzle.d.ts +1 -1
  232. package/lib/types/KuzzleDocument.d.ts +1 -1
  233. package/lib/types/OpenApiDefinition.d.ts +1 -1
  234. package/lib/types/PasswordPolicy.d.ts +1 -1
  235. package/lib/types/Plugin.d.ts +6 -6
  236. package/lib/types/Plugin.js +2 -2
  237. package/lib/types/Policy.d.ts +1 -1
  238. package/lib/types/RequestPayload.d.ts +1 -1
  239. package/lib/types/ResponsePayload.d.ts +1 -1
  240. package/lib/types/Token.d.ts +1 -1
  241. package/lib/types/User.d.ts +1 -1
  242. package/lib/types/config/DumpConfiguration.d.ts +8 -8
  243. package/lib/types/config/HttpConfiguration.d.ts +1 -1
  244. package/lib/types/config/KuzzleConfiguration.d.ts +1 -1
  245. package/lib/types/config/LimitsConfiguration.d.ts +8 -8
  246. package/lib/types/config/PluginsConfiguration.d.ts +4 -4
  247. package/lib/types/config/SecurityConfiguration.d.ts +62 -62
  248. package/lib/types/config/ServerConfiguration.d.ts +55 -55
  249. package/lib/types/config/ServicesConfiguration.d.ts +2 -2
  250. package/lib/types/config/internalCache/InternalCacheRedisConfiguration.d.ts +10 -10
  251. package/lib/types/config/publicCache/PublicCacheRedisConfiguration.d.ts +3 -3
  252. package/lib/types/config/storageEngine/StorageEngineElasticsearchConfiguration.d.ts +194 -110
  253. package/lib/types/errors/ErrorDefinition.d.ts +1 -1
  254. package/lib/types/errors/ErrorDomains.d.ts +1 -1
  255. package/lib/types/index.d.ts +38 -38
  256. package/lib/types/realtime/RealtimeScope.d.ts +1 -1
  257. package/lib/types/realtime/RealtimeUsers.d.ts +1 -1
  258. package/lib/util/assertType.js +13 -11
  259. package/lib/util/async.d.ts +1 -0
  260. package/lib/util/async.js +61 -0
  261. package/lib/util/asyncStore.js +19 -21
  262. package/lib/util/bufferedPassThrough.d.ts +2 -2
  263. package/lib/util/bufferedPassThrough.js +4 -4
  264. package/lib/util/bytes.js +9 -13
  265. package/lib/util/crypto.js +1 -1
  266. package/lib/util/debug.js +5 -5
  267. package/lib/util/deprecate.js +24 -21
  268. package/lib/util/didYouMean.js +7 -7
  269. package/lib/util/dump-collection.d.ts +2 -2
  270. package/lib/util/dump-collection.js +26 -26
  271. package/lib/util/esRequest.d.ts +1 -0
  272. package/lib/util/esRequest.js +62 -0
  273. package/lib/util/extractFields.js +24 -25
  274. package/lib/util/inflector.js +5 -5
  275. package/lib/util/koncordeCompat.d.ts +2 -2
  276. package/lib/util/koncordeCompat.js +5 -5
  277. package/lib/util/memoize.js +3 -5
  278. package/lib/util/mutex.d.ts +19 -1
  279. package/lib/util/mutex.js +39 -12
  280. package/lib/util/name-generator.js +1331 -1331
  281. package/lib/util/promback.js +8 -10
  282. package/lib/util/readYamlFile.d.ts +1 -1
  283. package/lib/util/readYamlFile.js +1 -1
  284. package/lib/util/requestAssertions.js +34 -34
  285. package/lib/util/safeObject.js +5 -5
  286. package/lib/util/stackTrace.js +20 -22
  287. package/lib/util/wildcard.js +15 -15
  288. package/package.json +6 -6
  289. package/npm-shrinkwrap.json +0 -19422
@@ -19,24 +19,24 @@
19
19
  * limitations under the License.
20
20
  */
21
21
 
22
- 'use strict';
22
+ "use strict";
23
23
 
24
- const Bluebird = require('bluebird');
25
- const _ = require('lodash');
26
- const { Koncorde } = require('koncorde');
24
+ const Bluebird = require("bluebird");
25
+ const _ = require("lodash");
26
+ const { Koncorde } = require("koncorde");
27
27
 
28
- const debug = require('../../util/debug')('core:validation');
29
- const kerror = require('../../kerror');
30
- const { KuzzleError } = require('../../kerror/errors');
31
- const { has, isPlainObject, get } = require('../../util/safeObject');
32
- const { koncordeTest, toKoncordeIndex } = require('../../util/koncordeCompat');
28
+ const debug = require("../../util/debug")("core:validation");
29
+ const kerror = require("../../kerror");
30
+ const { KuzzleError } = require("../../kerror/errors");
31
+ const { has, isPlainObject, get } = require("../../util/safeObject");
32
+ const { koncordeTest, toKoncordeIndex } = require("../../util/koncordeCompat");
33
33
 
34
- const assertionError = kerror.wrap('validation', 'assert');
34
+ const assertionError = kerror.wrap("validation", "assert");
35
35
  /**
36
36
  * @class Validation
37
37
  */
38
38
  class Validation {
39
- constructor () {
39
+ constructor() {
40
40
  /** @type {...ValidationType} */
41
41
  this.types = {};
42
42
 
@@ -55,22 +55,22 @@ class Validation {
55
55
  /**
56
56
  * Walks through all types in "defaultTypesFiles" initializes all types
57
57
  */
58
- init () {
58
+ init() {
59
59
  [
60
- 'anything',
61
- 'boolean',
62
- 'date',
63
- 'email',
64
- 'enum',
65
- 'geoPoint',
66
- 'geoShape',
67
- 'integer',
68
- 'ipAddress',
69
- 'numeric',
70
- 'object',
71
- 'string',
72
- 'url'
73
- ].forEach(typeFile => {
60
+ "anything",
61
+ "boolean",
62
+ "date",
63
+ "email",
64
+ "enum",
65
+ "geoPoint",
66
+ "geoShape",
67
+ "integer",
68
+ "ipAddress",
69
+ "numeric",
70
+ "object",
71
+ "string",
72
+ "url",
73
+ ].forEach((typeFile) => {
74
74
  const TypeConstructor = require(`./types/${typeFile}`);
75
75
  this.addType(new TypeConstructor());
76
76
  });
@@ -83,28 +83,29 @@ class Validation {
83
83
  * @param {boolean} [verbose]
84
84
  * @returns {Promise.<{documentBody: *, errorMessages:string[], valid: boolean}|KuzzleRequest>}
85
85
  */
86
- async validate (request, verbose = false) {
87
- const
88
- { _id, index, collection } = request.input.resource,
86
+ async validate(request, verbose = false) {
87
+ const { _id, index, collection } = request.input.resource,
89
88
  collectionSpec =
90
- isPlainObject(this.specification) &&
91
- has(this.specification, index) &&
92
- get(this.specification[index], collection) || {};
89
+ (isPlainObject(this.specification) &&
90
+ has(this.specification, index) &&
91
+ get(this.specification[index], collection)) ||
92
+ {};
93
93
 
94
- let
95
- isUpdate = false,
94
+ let isUpdate = false,
96
95
  body = request.input.body;
97
96
 
98
- if ( request.input.controller === 'document'
99
- && request.input.action === 'update'
97
+ if (
98
+ request.input.controller === "document" &&
99
+ request.input.action === "update"
100
100
  ) {
101
101
  isUpdate = true;
102
102
 
103
103
  const document = await global.kuzzle.ask(
104
- 'core:storage:public:document:get',
104
+ "core:storage:public:document:get",
105
105
  index,
106
106
  collection,
107
- _id);
107
+ _id
108
+ );
108
109
 
109
110
  // Avoid side effects on the request during the update validation
110
111
  body = _.cloneDeep(request.input.body);
@@ -122,45 +123,54 @@ class Validation {
122
123
  collectionSpec.fields.children,
123
124
  collectionSpec.strict,
124
125
  errorMessages,
125
- verbose);
126
- }
127
- catch (error) {
126
+ verbose
127
+ );
128
+ } catch (error) {
128
129
  // The strictness message can be received here only if it happens at
129
130
  // the validation of the document's root
130
- if (error.message !== 'strictness') {
131
+ if (error.message !== "strictness") {
131
132
  throw error;
132
133
  }
133
134
 
134
135
  isValid = false;
135
136
  manageErrorMessage(
136
- 'document',
137
+ "document",
137
138
  errorMessages,
138
139
  `The document validation is strict. Cannot add unspecified sub-field "${error.details.field}"`,
139
- verbose);
140
+ verbose
141
+ );
140
142
  }
141
143
  }
142
144
 
143
145
  if (collectionSpec.validators) {
144
- const filters = koncordeTest(this.koncorde, index, collection, body, _id);
146
+ const filters = koncordeTest(
147
+ this.koncorde,
148
+ index,
149
+ collection,
150
+ body,
151
+ _id
152
+ );
145
153
 
146
- if ( filters.length === 0 || filters[0] !== collectionSpec.validators) {
154
+ if (filters.length === 0 || filters[0] !== collectionSpec.validators) {
147
155
  isValid = false;
148
156
  manageErrorMessage(
149
- 'document',
157
+ "document",
150
158
  errorMessages,
151
- 'The document does not match validation filters.',
152
- verbose);
159
+ "The document does not match validation filters.",
160
+ verbose
161
+ );
153
162
  }
154
163
  }
155
164
  }
156
165
 
157
- if (! verbose) {
166
+ if (!verbose) {
158
167
  // We only modify the request if the validation succeeds
159
168
  if (collectionSpec.fields && collectionSpec.fields.children) {
160
169
  request.input.body = this.recurseApplyDefault(
161
170
  isUpdate,
162
171
  request.input.body,
163
- collectionSpec.fields.children);
172
+ collectionSpec.fields.children
173
+ );
164
174
  }
165
175
 
166
176
  return request;
@@ -174,32 +184,34 @@ class Validation {
174
184
  * @param {*} documentSubset
175
185
  * @param {...StructuredFieldSpecification} collectionSpecSubset
176
186
  */
177
- recurseApplyDefault (isUpdate, documentSubset, collectionSpecSubset) {
178
- Object.keys(collectionSpecSubset).forEach(fieldName => {
179
- const
180
- specSubset = collectionSpecSubset[fieldName],
187
+ recurseApplyDefault(isUpdate, documentSubset, collectionSpecSubset) {
188
+ Object.keys(collectionSpecSubset).forEach((fieldName) => {
189
+ const specSubset = collectionSpecSubset[fieldName],
181
190
  field = documentSubset[fieldName];
182
191
 
183
- if (has(documentSubset, fieldName)
184
- && this.types[specSubset.type].allowChildren && specSubset.children
192
+ if (
193
+ has(documentSubset, fieldName) &&
194
+ this.types[specSubset.type].allowChildren &&
195
+ specSubset.children
185
196
  ) {
186
197
  if (Array.isArray(field)) {
187
198
  for (let i = 0; i < field.length; i++) {
188
199
  field[i] = this.recurseApplyDefault(
189
200
  isUpdate,
190
201
  field[i],
191
- specSubset.children);
202
+ specSubset.children
203
+ );
192
204
  }
193
- }
194
- else {
205
+ } else {
195
206
  documentSubset[fieldName] = this.recurseApplyDefault(
196
207
  isUpdate,
197
208
  field,
198
- specSubset.children);
209
+ specSubset.children
210
+ );
199
211
  }
200
- }
201
- else if (specSubset.defaultValue
202
- && (field === null || (! isUpdate && ! has(documentSubset, fieldName)))
212
+ } else if (
213
+ specSubset.defaultValue &&
214
+ (field === null || (!isUpdate && !has(documentSubset, fieldName)))
203
215
  ) {
204
216
  documentSubset[fieldName] = specSubset.defaultValue;
205
217
  }
@@ -215,7 +227,7 @@ class Validation {
215
227
  * @param {string[]} errorMessages
216
228
  * @param {boolean} verbose
217
229
  */
218
- recurseFieldValidation (
230
+ recurseFieldValidation(
219
231
  documentSubset,
220
232
  collectionSpecSubset,
221
233
  strictness,
@@ -224,36 +236,41 @@ class Validation {
224
236
  ) {
225
237
  if (strictness) {
226
238
  for (const field of Object.keys(documentSubset)) {
227
- if (! collectionSpecSubset[field]) {
228
- const error = new Error('strictness');
239
+ if (!collectionSpecSubset[field]) {
240
+ const error = new Error("strictness");
229
241
  error.details = { field };
230
242
  throw error;
231
243
  }
232
244
  }
233
245
  }
234
246
 
235
- if (! verbose) {
247
+ if (!verbose) {
236
248
  // We stop as soon as one field is not valid
237
- return Object.keys(collectionSpecSubset).every(fieldName =>
249
+ return Object.keys(collectionSpecSubset).every((fieldName) =>
238
250
  this.isValidField(
239
251
  fieldName,
240
252
  documentSubset,
241
253
  collectionSpecSubset,
242
254
  strictness,
243
255
  errorMessages,
244
- verbose));
256
+ verbose
257
+ )
258
+ );
245
259
  }
246
260
 
247
261
  // We try to validate every field in order to get all error messages if any
248
262
  return Object.keys(collectionSpecSubset).reduce(
249
- (reductionResult, fieldName) => this.isValidField(
250
- fieldName,
251
- documentSubset,
252
- collectionSpecSubset,
253
- strictness,
254
- errorMessages,
255
- verbose) && reductionResult,
256
- true);
263
+ (reductionResult, fieldName) =>
264
+ this.isValidField(
265
+ fieldName,
266
+ documentSubset,
267
+ collectionSpecSubset,
268
+ strictness,
269
+ errorMessages,
270
+ verbose
271
+ ) && reductionResult,
272
+ true
273
+ );
257
274
  }
258
275
 
259
276
  /**
@@ -265,7 +282,7 @@ class Validation {
265
282
  * @param {boolean} verbose
266
283
  * @returns {boolean}
267
284
  */
268
- isValidField (
285
+ isValidField(
269
286
  fieldName,
270
287
  documentSubset,
271
288
  collectionSpecSubset,
@@ -277,64 +294,70 @@ class Validation {
277
294
  const field = collectionSpecSubset[fieldName];
278
295
  let result = true;
279
296
 
280
- if (field.mandatory
281
- && ! has(field, 'defaultValue')
282
- && _.isNil(documentSubset[fieldName])
297
+ if (
298
+ field.mandatory &&
299
+ !has(field, "defaultValue") &&
300
+ _.isNil(documentSubset[fieldName])
283
301
  ) {
284
302
  manageErrorMessage(
285
303
  field.path,
286
304
  errorMessages,
287
- 'The field is mandatory.',
288
- verbose);
305
+ "The field is mandatory.",
306
+ verbose
307
+ );
289
308
  return false;
290
309
  }
291
310
 
292
- if (! _.isNil(documentSubset[fieldName])) {
293
- let
294
- nestedStrictness = false,
311
+ if (!_.isNil(documentSubset[fieldName])) {
312
+ let nestedStrictness = false,
295
313
  fieldValues;
296
314
 
297
315
  if (field.multivalued.value) {
298
- if (! Array.isArray(documentSubset[fieldName])) {
316
+ if (!Array.isArray(documentSubset[fieldName])) {
299
317
  manageErrorMessage(
300
318
  field.path,
301
319
  errorMessages,
302
- 'The field must be multivalued, unary value provided.',
303
- verbose);
320
+ "The field must be multivalued, unary value provided.",
321
+ verbose
322
+ );
304
323
  return false;
305
324
  }
306
325
 
307
- if ( has(field.multivalued, 'minCount')
308
- && documentSubset[fieldName].length < field.multivalued.minCount
326
+ if (
327
+ has(field.multivalued, "minCount") &&
328
+ documentSubset[fieldName].length < field.multivalued.minCount
309
329
  ) {
310
330
  manageErrorMessage(
311
331
  field.path,
312
332
  errorMessages,
313
333
  `Not enough elements. Minimum count is set to ${field.multivalued.minCount}.`,
314
- verbose);
334
+ verbose
335
+ );
315
336
  return false;
316
337
  }
317
338
 
318
- if ( has(field.multivalued, 'maxCount')
319
- && documentSubset[fieldName].length > field.multivalued.maxCount
339
+ if (
340
+ has(field.multivalued, "maxCount") &&
341
+ documentSubset[fieldName].length > field.multivalued.maxCount
320
342
  ) {
321
343
  manageErrorMessage(
322
344
  field.path,
323
345
  errorMessages,
324
346
  `Too many elements. Maximum count is set to ${field.multivalued.maxCount}.`,
325
- verbose);
347
+ verbose
348
+ );
326
349
  return false;
327
350
  }
328
351
 
329
352
  fieldValues = documentSubset[fieldName];
330
- }
331
- else {
353
+ } else {
332
354
  if (Array.isArray(documentSubset[fieldName])) {
333
355
  manageErrorMessage(
334
356
  field.path,
335
357
  errorMessages,
336
- 'The field is not a multivalued field; Multiple values provided.',
337
- verbose);
358
+ "The field is not a multivalued field; Multiple values provided.",
359
+ verbose
360
+ );
338
361
  return false;
339
362
  }
340
363
 
@@ -344,64 +367,61 @@ class Validation {
344
367
  if (this.types[field.type].allowChildren) {
345
368
  nestedStrictness = this.types[field.type].getStrictness(
346
369
  field.typeOptions,
347
- strictness);
370
+ strictness
371
+ );
348
372
  }
349
373
 
350
374
  for (const val of fieldValues) {
351
375
  const fieldErrors = [];
352
376
 
353
- if (! this.types[field.type].validate(
354
- field.typeOptions,
355
- val,
356
- fieldErrors)
377
+ if (
378
+ !this.types[field.type].validate(field.typeOptions, val, fieldErrors)
357
379
  ) {
358
380
  if (fieldErrors.length === 0) {
359
381
  // We still want to trigger an error, even if no message is provided
360
382
  manageErrorMessage(
361
383
  field.path,
362
384
  errorMessages,
363
- 'An error has occurred during validation.',
364
- verbose);
365
- }
366
- else {
367
- fieldErrors.forEach(
368
- message => manageErrorMessage(
369
- field.path,
370
- errorMessages,
371
- message,
372
- verbose));
385
+ "An error has occurred during validation.",
386
+ verbose
387
+ );
388
+ } else {
389
+ fieldErrors.forEach((message) =>
390
+ manageErrorMessage(field.path, errorMessages, message, verbose)
391
+ );
373
392
  }
374
393
  return false;
375
394
  }
376
395
 
377
396
  if (this.types[field.type].allowChildren && field.children) {
378
397
  try {
379
- if (! this.recurseFieldValidation(
380
- val,
381
- field.children,
382
- nestedStrictness,
383
- errorMessages,
384
- verbose
385
- )) {
398
+ if (
399
+ !this.recurseFieldValidation(
400
+ val,
401
+ field.children,
402
+ nestedStrictness,
403
+ errorMessages,
404
+ verbose
405
+ )
406
+ ) {
386
407
  result = false;
387
408
  }
388
- }
389
- catch (error) {
390
- if (error.message === 'strictness') {
409
+ } catch (error) {
410
+ if (error.message === "strictness") {
391
411
  manageErrorMessage(
392
412
  field.path,
393
413
  errorMessages,
394
414
  `The field is set to "strict"; cannot add unspecified sub-field "${error.details.field}".`,
395
- verbose);
396
- }
397
- else if (verbose) {
415
+ verbose
416
+ );
417
+ } else if (verbose) {
398
418
  manageErrorMessage(
399
419
  field.path,
400
420
  errorMessages,
401
421
  error.message,
402
- verbose);
403
- }
404
- else {
422
+ verbose
423
+ );
424
+ } else {
405
425
  throw error;
406
426
  }
407
427
 
@@ -416,51 +436,47 @@ class Validation {
416
436
  /**
417
437
  * @returns {Promise.<T>}
418
438
  */
419
- curateSpecification () {
420
- const
421
- promises = [],
439
+ curateSpecification() {
440
+ const promises = [],
422
441
  specification = {};
423
442
 
424
- return getValidationConfiguration()
425
- .then(validation => {
426
- this.rawConfiguration = validation;
427
-
428
- for (const indexName of Object.keys(this.rawConfiguration)) {
429
- for (const collectionName of Object.keys(
430
- this.rawConfiguration[indexName])
431
- ) {
432
- const promise = this.curateCollectionSpecification(
433
- indexName,
434
- collectionName,
435
- this.rawConfiguration[indexName][collectionName]
436
- )
437
- .then(curatedSpec => {
438
-
439
- if (! has(specification, indexName)) {
440
- specification[indexName] = {};
441
- }
442
-
443
- specification[indexName][collectionName] = curatedSpec;
444
-
445
- return null;
446
- })
447
- .catch(error => {
448
- global.kuzzle.log.error(
449
- `Specification for the collection ${collectionName} triggered an error`);
450
- global.kuzzle.log.error(`Error: ${error.message}`);
451
-
452
- return null;
453
- });
454
- promises.push(promise);
455
- }
443
+ return getValidationConfiguration().then((validation) => {
444
+ this.rawConfiguration = validation;
445
+
446
+ for (const indexName of Object.keys(this.rawConfiguration)) {
447
+ for (const collectionName of Object.keys(
448
+ this.rawConfiguration[indexName]
449
+ )) {
450
+ const promise = this.curateCollectionSpecification(
451
+ indexName,
452
+ collectionName,
453
+ this.rawConfiguration[indexName][collectionName]
454
+ )
455
+ .then((curatedSpec) => {
456
+ if (!has(specification, indexName)) {
457
+ specification[indexName] = {};
458
+ }
459
+
460
+ specification[indexName][collectionName] = curatedSpec;
461
+
462
+ return null;
463
+ })
464
+ .catch((error) => {
465
+ global.kuzzle.log.error(
466
+ `Specification for the collection ${collectionName} triggered an error`
467
+ );
468
+ global.kuzzle.log.error(`Error: ${error.message}`);
469
+
470
+ return null;
471
+ });
472
+ promises.push(promise);
456
473
  }
474
+ }
457
475
 
458
- return Bluebird
459
- .all(promises)
460
- .then(() => {
461
- this.specification = specification;
462
- });
476
+ return Bluebird.all(promises).then(() => {
477
+ this.specification = specification;
463
478
  });
479
+ });
464
480
  }
465
481
 
466
482
  /**
@@ -470,7 +486,7 @@ class Validation {
470
486
  * @param {boolean} [verboseErrors]
471
487
  * @returns {Promise<object>}
472
488
  */
473
- validateFormat (
489
+ validateFormat(
474
490
  indexName,
475
491
  collectionName,
476
492
  collectionSpec,
@@ -479,21 +495,24 @@ class Validation {
479
495
  // We make a deep clone to avoid side effects
480
496
  const specification = _.cloneDeep(collectionSpec);
481
497
 
482
- return this.curateCollectionSpecification(
483
- indexName,
484
- collectionName,
485
- specification,
486
- true,
487
- verboseErrors)
488
- .then(result => {
489
- if (verboseErrors && result.isValid === false) {
490
- return result;
491
- }
492
- return { isValid: true };
493
- })
494
- // we do not want to reject since this method goal is
495
- // to know what is going wrong with the given spec
496
- .catch(error => ({ errors: [error], isValid: false }));
498
+ return (
499
+ this.curateCollectionSpecification(
500
+ indexName,
501
+ collectionName,
502
+ specification,
503
+ true,
504
+ verboseErrors
505
+ )
506
+ .then((result) => {
507
+ if (verboseErrors && result.isValid === false) {
508
+ return result;
509
+ }
510
+ return { isValid: true };
511
+ })
512
+ // we do not want to reject since this method goal is
513
+ // to know what is going wrong with the given spec
514
+ .catch((error) => ({ errors: [error], isValid: false }))
515
+ );
497
516
  }
498
517
 
499
518
  /**
@@ -505,26 +524,27 @@ class Validation {
505
524
  * @returns {Promise<CollectionSpecification>}
506
525
  * @rejects PreconditionError
507
526
  */
508
- async curateCollectionSpecification (
527
+ async curateCollectionSpecification(
509
528
  index,
510
529
  collection,
511
530
  spec,
512
531
  dryRun = false,
513
532
  verbose = false
514
533
  ) {
515
- let error = '';
534
+ let error = "";
516
535
  const processed = {
517
536
  fields: {},
518
537
  strict: spec.strict || false,
519
- validators: null
538
+ validators: null,
520
539
  };
521
- const allowed = ['strict', 'fields', 'validators'];
540
+ const allowed = ["strict", "fields", "validators"];
522
541
 
523
- if (! checkAllowedProperties(spec, allowed)) {
542
+ if (!checkAllowedProperties(spec, allowed)) {
524
543
  error = assertionError.get(
525
- 'unexpected_properties',
544
+ "unexpected_properties",
526
545
  `${index}.${collection}`,
527
- allowed.join(', '));
546
+ allowed.join(", ")
547
+ );
528
548
 
529
549
  if (verbose) {
530
550
  return { errors: [error.message], isValid: false };
@@ -538,7 +558,8 @@ class Validation {
538
558
  spec,
539
559
  index,
540
560
  collection,
541
- verbose);
561
+ verbose
562
+ );
542
563
 
543
564
  if (result.isValid === false) {
544
565
  if (verbose) {
@@ -546,7 +567,10 @@ class Validation {
546
567
  return result;
547
568
  }
548
569
 
549
- throw assertionError.get('invalid_specifications', result.errors.join('\n\t- '));
570
+ throw assertionError.get(
571
+ "invalid_specifications",
572
+ result.errors.join("\n\t- ")
573
+ );
550
574
  }
551
575
  processed.fields = result;
552
576
  }
@@ -557,33 +581,31 @@ class Validation {
557
581
  index,
558
582
  collection,
559
583
  spec.validators,
560
- dryRun);
584
+ dryRun
585
+ );
561
586
 
562
587
  processed.validators = filterId;
563
- }
564
- catch (e) {
588
+ } catch (e) {
565
589
  global.kuzzle.log.error(e);
566
- throw assertionError.getFrom(e, 'invalid_filters', e.message);
590
+ throw assertionError.getFrom(e, "invalid_filters", e.message);
567
591
  }
568
592
  }
569
593
 
570
594
  return processed;
571
595
  }
572
596
 
573
- structureCollectionValidation (
597
+ structureCollectionValidation(
574
598
  collectionSpec,
575
599
  indexName,
576
600
  collectionName,
577
601
  verboseErrors = false
578
602
  ) {
579
603
  const fields = {};
580
- let
581
- errors = [],
604
+ let errors = [],
582
605
  maxDepth = 0;
583
606
 
584
607
  for (const fieldName of Object.keys(collectionSpec.fields)) {
585
- const
586
- // We deep clone the field because we will modify it
608
+ const // We deep clone the field because we will modify it
587
609
  fieldSpecClone = _.cloneDeep(collectionSpec.fields[fieldName]);
588
610
 
589
611
  try {
@@ -592,30 +614,29 @@ class Validation {
592
614
  indexName,
593
615
  collectionName,
594
616
  fieldName,
595
- verboseErrors);
617
+ verboseErrors
618
+ );
596
619
 
597
620
  if (result.isValid === false) {
598
621
  errors = _.concat(errors, result.errors);
599
- global.kuzzle.log.error(result.errors.join('\n'));
600
- }
601
- else {
622
+ global.kuzzle.log.error(result.errors.join("\n"));
623
+ } else {
602
624
  const field = result.fieldSpec;
603
625
 
604
- field.path = fieldName.split('/');
626
+ field.path = fieldName.split("/");
605
627
  field.depth = field.path.length;
606
628
 
607
629
  if (field.depth > maxDepth) {
608
630
  maxDepth = field.depth;
609
631
  }
610
632
 
611
- if (! fields[field.depth]) {
633
+ if (!fields[field.depth]) {
612
634
  fields[field.depth] = [];
613
635
  }
614
636
 
615
637
  fields[field.depth].push(field);
616
638
  }
617
- }
618
- catch (error) {
639
+ } catch (error) {
619
640
  global.kuzzle.log.error(error);
620
641
  throwOrStoreError(error, verboseErrors, errors);
621
642
  }
@@ -640,7 +661,7 @@ class Validation {
640
661
  * @returns {object}
641
662
  * @throws PreconditionError
642
663
  */
643
- curateFieldSpecification (
664
+ curateFieldSpecification(
644
665
  fieldSpec,
645
666
  indexName,
646
667
  collectionName,
@@ -662,43 +683,46 @@ class Validation {
662
683
  }
663
684
 
664
685
  _.defaultsDeep(fieldSpec, {
665
- 'mandatory': false,
666
- 'multivalued': {
667
- value: false
668
- }
686
+ mandatory: false,
687
+ multivalued: {
688
+ value: false,
689
+ },
669
690
  });
670
691
 
671
- if (! has(fieldSpec, 'typeOptions')) {
692
+ if (!has(fieldSpec, "typeOptions")) {
672
693
  fieldSpec.typeOptions = {};
673
694
  }
674
695
 
675
696
  const allowed = this.types[fieldSpec.type].allowedTypeOptions || [];
676
697
 
677
- if (! checkAllowedProperties(fieldSpec.typeOptions, allowed)) {
698
+ if (!checkAllowedProperties(fieldSpec.typeOptions, allowed)) {
678
699
  throwOrStoreError(
679
700
  assertionError.get(
680
- 'unexpected_properties',
701
+ "unexpected_properties",
681
702
  `${indexName}.${collectionName}.${fieldName}`,
682
- allowed.join(', ')),
703
+ allowed.join(", ")
704
+ ),
683
705
  verboseErrors,
684
- errors);
706
+ errors
707
+ );
685
708
  }
686
709
 
687
710
  try {
688
- fieldSpec.typeOptions = this.types[fieldSpec.type]
689
- .validateFieldSpecification(fieldSpec.typeOptions);
690
- }
691
- catch (e) {
692
- if (! verboseErrors) {
711
+ fieldSpec.typeOptions = this.types[
712
+ fieldSpec.type
713
+ ].validateFieldSpecification(fieldSpec.typeOptions);
714
+ } catch (e) {
715
+ if (!verboseErrors) {
693
716
  if (e instanceof KuzzleError) {
694
717
  throw e;
695
718
  }
696
719
  throw kerror.getFrom(
697
720
  e,
698
- 'plugin',
699
- 'runtime',
700
- 'unexpected_error',
701
- e.message);
721
+ "plugin",
722
+ "runtime",
723
+ "unexpected_error",
724
+ e.message
725
+ );
702
726
  }
703
727
 
704
728
  errors.push(e.message);
@@ -709,11 +733,12 @@ class Validation {
709
733
  }
710
734
 
711
735
  debug(
712
- 'Loaded field validator: %s/%s/%s: %o',
736
+ "Loaded field validator: %s/%s/%s: %o",
713
737
  indexName,
714
738
  collectionName,
715
739
  fieldName,
716
- fieldSpec);
740
+ fieldSpec
741
+ );
717
742
 
718
743
  return { fieldSpec, isValid: true };
719
744
  }
@@ -727,7 +752,7 @@ class Validation {
727
752
  * @returns {object}
728
753
  * @throws PreconditionError
729
754
  */
730
- curateFieldSpecificationFormat (
755
+ curateFieldSpecificationFormat(
731
756
  fieldSpec,
732
757
  indexName,
733
758
  collectionName,
@@ -737,100 +762,118 @@ class Validation {
737
762
  const errors = [];
738
763
 
739
764
  const props = [
740
- 'mandatory',
741
- 'type',
742
- 'defaultValue',
743
- 'description',
744
- 'multivalued',
745
- 'typeOptions'
765
+ "mandatory",
766
+ "type",
767
+ "defaultValue",
768
+ "description",
769
+ "multivalued",
770
+ "typeOptions",
746
771
  ];
747
772
 
748
- if (! checkAllowedProperties(fieldSpec, props)) {
773
+ if (!checkAllowedProperties(fieldSpec, props)) {
749
774
  throwOrStoreError(
750
775
  assertionError.get(
751
- 'unexpected_properties',
776
+ "unexpected_properties",
752
777
  `${indexName}.${collectionName}.${fieldName}`,
753
- props.join(', ')),
778
+ props.join(", ")
779
+ ),
754
780
  verboseErrors,
755
- errors);
781
+ errors
782
+ );
756
783
  }
757
784
 
758
- if (! has(fieldSpec, 'type')) {
785
+ if (!has(fieldSpec, "type")) {
759
786
  throwOrStoreError(
760
787
  assertionError.get(
761
- 'missing_type',
762
- `${indexName}.${collectionName}.${fieldName}`),
788
+ "missing_type",
789
+ `${indexName}.${collectionName}.${fieldName}`
790
+ ),
763
791
  verboseErrors,
764
- errors);
792
+ errors
793
+ );
765
794
  }
766
795
 
767
- if (! has(this.types, fieldSpec.type)) {
796
+ if (!has(this.types, fieldSpec.type)) {
768
797
  throwOrStoreError(
769
798
  assertionError.get(
770
- 'unknown_type',
799
+ "unknown_type",
771
800
  `${indexName}.${collectionName}.${fieldName}`,
772
- fieldSpec.type),
801
+ fieldSpec.type
802
+ ),
773
803
  verboseErrors,
774
- errors);
804
+ errors
805
+ );
775
806
  }
776
807
 
777
- if (has(fieldSpec, 'multivalued')) {
778
- const multivaluedProps = ['value', 'minCount', 'maxCount'];
779
- if (! checkAllowedProperties(fieldSpec.multivalued, multivaluedProps)) {
808
+ if (has(fieldSpec, "multivalued")) {
809
+ const multivaluedProps = ["value", "minCount", "maxCount"];
810
+ if (!checkAllowedProperties(fieldSpec.multivalued, multivaluedProps)) {
780
811
  throwOrStoreError(
781
812
  assertionError.get(
782
- 'unexpected_properties',
813
+ "unexpected_properties",
783
814
  `${indexName}.${collectionName}.${fieldName}.multivalued`,
784
- multivaluedProps.join(', ')),
815
+ multivaluedProps.join(", ")
816
+ ),
785
817
  verboseErrors,
786
- errors);
818
+ errors
819
+ );
787
820
  }
788
821
 
789
- if (! has(fieldSpec.multivalued, 'value')) {
822
+ if (!has(fieldSpec.multivalued, "value")) {
790
823
  throwOrStoreError(
791
824
  assertionError.get(
792
- 'missing_value',
793
- `${indexName}.${collectionName}.${fieldName}.multivalued`),
825
+ "missing_value",
826
+ `${indexName}.${collectionName}.${fieldName}.multivalued`
827
+ ),
794
828
  verboseErrors,
795
- errors);
829
+ errors
830
+ );
796
831
  }
797
832
 
798
- if (typeof fieldSpec.multivalued.value !== 'boolean') {
833
+ if (typeof fieldSpec.multivalued.value !== "boolean") {
799
834
  throwOrStoreError(
800
835
  assertionError.get(
801
- 'invalid_type',
836
+ "invalid_type",
802
837
  `${indexName}.${collectionName}.${fieldName}.multivalued.value`,
803
- 'boolean'),
838
+ "boolean"
839
+ ),
804
840
  verboseErrors,
805
- errors);
841
+ errors
842
+ );
806
843
  }
807
844
 
808
- for (const unexpected of ['minCount', 'maxCount']) {
809
- if ( ! fieldSpec.multivalued.value
810
- && has(fieldSpec.multivalued, unexpected)
845
+ for (const unexpected of ["minCount", "maxCount"]) {
846
+ if (
847
+ !fieldSpec.multivalued.value &&
848
+ has(fieldSpec.multivalued, unexpected)
811
849
  ) {
812
850
  throwOrStoreError(
813
851
  assertionError.get(
814
- 'not_multivalued',
852
+ "not_multivalued",
815
853
  `${indexName}.${collectionName}.${fieldName}`,
816
- unexpected),
854
+ unexpected
855
+ ),
817
856
  verboseErrors,
818
- errors);
857
+ errors
858
+ );
819
859
  }
820
860
  }
821
861
 
822
- if ( has(fieldSpec.multivalued, 'minCount')
823
- && has(fieldSpec.multivalued, 'maxCount')
824
- && fieldSpec.multivalued.minCount > fieldSpec.multivalued.maxCount
862
+ if (
863
+ has(fieldSpec.multivalued, "minCount") &&
864
+ has(fieldSpec.multivalued, "maxCount") &&
865
+ fieldSpec.multivalued.minCount > fieldSpec.multivalued.maxCount
825
866
  ) {
826
867
  throwOrStoreError(
827
868
  assertionError.get(
828
- 'invalid_range',
869
+ "invalid_range",
829
870
  `${indexName}.${collectionName}.${fieldName}`,
830
- 'minCount',
831
- 'maxCount'),
871
+ "minCount",
872
+ "maxCount"
873
+ ),
832
874
  verboseErrors,
833
- errors);
875
+ errors
876
+ );
834
877
  }
835
878
  }
836
879
 
@@ -848,25 +891,27 @@ class Validation {
848
891
  * @param {boolean} dryRun
849
892
  * @returns {string}
850
893
  */
851
- curateValidatorFilter (indexName, collectionName, validatorFilter, dryRun) {
894
+ curateValidatorFilter(indexName, collectionName, validatorFilter, dryRun) {
852
895
  const query = {
853
896
  bool: {
854
- must: validatorFilter
855
- }
897
+ must: validatorFilter,
898
+ },
856
899
  };
857
900
 
858
901
  this.koncorde.validate(query);
859
902
 
860
- if (! dryRun) {
903
+ if (!dryRun) {
861
904
  debug(
862
- 'Registering filter validator %s/%s: %O',
905
+ "Registering filter validator %s/%s: %O",
863
906
  indexName,
864
907
  collectionName,
865
- query);
908
+ query
909
+ );
866
910
 
867
911
  return this.koncorde.register(
868
912
  query,
869
- toKoncordeIndex(indexName, collectionName));
913
+ toKoncordeIndex(indexName, collectionName)
914
+ );
870
915
  }
871
916
 
872
917
  return null;
@@ -876,45 +921,49 @@ class Validation {
876
921
  * @param {ValidationType} validationType
877
922
  * @throws {PluginImplementationError}
878
923
  */
879
- addType (validationType) {
880
- if (! validationType.typeName) {
881
- throw kerror.get('validation', 'types', 'missing_type_name');
924
+ addType(validationType) {
925
+ if (!validationType.typeName) {
926
+ throw kerror.get("validation", "types", "missing_type_name");
882
927
  }
883
928
 
884
- if ( ! validationType.validate
885
- || typeof validationType.validate !== 'function'
929
+ if (
930
+ !validationType.validate ||
931
+ typeof validationType.validate !== "function"
886
932
  ) {
887
933
  throw kerror.get(
888
- 'validation',
889
- 'types',
890
- 'missing_function',
934
+ "validation",
935
+ "types",
936
+ "missing_function",
891
937
  validationType.typeName,
892
- 'validate');
938
+ "validate"
939
+ );
893
940
  }
894
941
 
895
- if ( ! validationType.validateFieldSpecification
896
- || typeof validationType.validateFieldSpecification !== 'function'
942
+ if (
943
+ !validationType.validateFieldSpecification ||
944
+ typeof validationType.validateFieldSpecification !== "function"
897
945
  ) {
898
946
  throw kerror.get(
899
- 'validation',
900
- 'types',
901
- 'missing_function',
947
+ "validation",
948
+ "types",
949
+ "missing_function",
902
950
  validationType.typeName,
903
- 'validateFieldSpecification');
951
+ "validateFieldSpecification"
952
+ );
904
953
  }
905
954
 
906
- if (has(validationType, 'allowChildren')
907
- && validationType.allowChildren
908
- ) {
909
- if (! validationType.getStrictness
910
- || typeof validationType.getStrictness !== 'function'
955
+ if (has(validationType, "allowChildren") && validationType.allowChildren) {
956
+ if (
957
+ !validationType.getStrictness ||
958
+ typeof validationType.getStrictness !== "function"
911
959
  ) {
912
960
  throw kerror.get(
913
- 'validation',
914
- 'types',
915
- 'missing_function',
961
+ "validation",
962
+ "types",
963
+ "missing_function",
916
964
  validationType.typeName,
917
- 'getStrictness');
965
+ "getStrictness"
966
+ );
918
967
  }
919
968
 
920
969
  this.typeAllowsChildren.push(validationType.typeName);
@@ -922,15 +971,15 @@ class Validation {
922
971
 
923
972
  if (this.types[validationType.typeName]) {
924
973
  throw kerror.get(
925
- 'validation',
926
- 'types',
927
- 'already_exists',
928
- validationType.typeName);
974
+ "validation",
975
+ "types",
976
+ "already_exists",
977
+ validationType.typeName
978
+ );
929
979
  }
930
980
 
931
981
  this.types[validationType.typeName] = validationType;
932
982
  }
933
-
934
983
  }
935
984
 
936
985
  /**
@@ -938,13 +987,14 @@ class Validation {
938
987
  * @param {string[]} allowedProperties
939
988
  * @returns {boolean}
940
989
  */
941
- function checkAllowedProperties (object, allowedProperties) {
942
- if (! isPlainObject(object)) {
990
+ function checkAllowedProperties(object, allowedProperties) {
991
+ if (!isPlainObject(object)) {
943
992
  return false;
944
993
  }
945
994
 
946
- return ! Object.keys(object).some(
947
- propertyName => ! allowedProperties.includes(propertyName));
995
+ return !Object.keys(object).some(
996
+ (propertyName) => !allowedProperties.includes(propertyName)
997
+ );
948
998
  }
949
999
 
950
1000
  /**
@@ -953,29 +1003,27 @@ function checkAllowedProperties (object, allowedProperties) {
953
1003
  * @param {number} maxDepth : depth of the fields; counting starts at 1
954
1004
  * @throws PreconditionError
955
1005
  */
956
- function curateStructuredFields (typeAllowsChildren, fields, maxDepth) {
957
- const
958
- /** @type StructuredFieldSpecification */
1006
+ function curateStructuredFields(typeAllowsChildren, fields, maxDepth) {
1007
+ const /** @type StructuredFieldSpecification */
959
1008
  structuredFields = {
960
1009
  children: {},
961
- root: true
1010
+ root: true,
962
1011
  };
963
1012
 
964
1013
  for (let i = 1; i <= maxDepth; i++) {
965
- if (! has(fields, i)) {
966
- throw assertionError.get('missing_nested_spec');
1014
+ if (!has(fields, i)) {
1015
+ throw assertionError.get("missing_nested_spec");
967
1016
  }
968
1017
 
969
- fields[i].forEach(field => {
970
- const
971
- parent = getParent(structuredFields, field.path),
1018
+ fields[i].forEach((field) => {
1019
+ const parent = getParent(structuredFields, field.path),
972
1020
  childKey = field.path[field.path.length - 1];
973
1021
 
974
- if (! parent.root && typeAllowsChildren.indexOf(parent.type) === -1) {
975
- throw assertionError.get('unexpected_children', parent.type);
1022
+ if (!parent.root && typeAllowsChildren.indexOf(parent.type) === -1) {
1023
+ throw assertionError.get("unexpected_children", parent.type);
976
1024
  }
977
1025
 
978
- if (! has(parent, 'children')) {
1026
+ if (!has(parent, "children")) {
979
1027
  parent.children = {};
980
1028
  }
981
1029
 
@@ -991,7 +1039,7 @@ function curateStructuredFields (typeAllowsChildren, fields, maxDepth) {
991
1039
  * @param {string[]}fieldPath
992
1040
  * @returns {StructuredFieldSpecification}
993
1041
  */
994
- function getParent (structuredFields, fieldPath) {
1042
+ function getParent(structuredFields, fieldPath) {
995
1043
  if (fieldPath.length === 1) {
996
1044
  return structuredFields;
997
1045
  }
@@ -999,8 +1047,8 @@ function getParent (structuredFields, fieldPath) {
999
1047
  let pointer = structuredFields;
1000
1048
 
1001
1049
  for (let i = 0; i < fieldPath.length - 1; i++) {
1002
- if (! has(pointer.children, fieldPath[i])) {
1003
- throw assertionError.get('missing_parent', fieldPath.join('.'));
1050
+ if (!has(pointer.children, fieldPath[i])) {
1051
+ throw assertionError.get("missing_parent", fieldPath.join("."));
1004
1052
  }
1005
1053
 
1006
1054
  pointer = pointer.children[fieldPath[i]];
@@ -1014,8 +1062,8 @@ function getParent (structuredFields, fieldPath) {
1014
1062
  * @param {boolean} doNotThrow
1015
1063
  * @param {string[]} errors
1016
1064
  */
1017
- function throwOrStoreError (error, doNotThrow, errorMessages) {
1018
- if (! doNotThrow) {
1065
+ function throwOrStoreError(error, doNotThrow, errorMessages) {
1066
+ if (!doNotThrow) {
1019
1067
  throw error;
1020
1068
  }
1021
1069
 
@@ -1028,50 +1076,48 @@ function throwOrStoreError (error, doNotThrow, errorMessages) {
1028
1076
  * @param {string} message
1029
1077
  * @param {boolean} structured
1030
1078
  */
1031
- function manageErrorMessage (errorContext, errorHolder, message, structured) {
1079
+ function manageErrorMessage(errorContext, errorHolder, message, structured) {
1032
1080
  if (structured) {
1033
- if (errorContext === 'document') {
1034
- if (! errorHolder.documentScope) {
1081
+ if (errorContext === "document") {
1082
+ if (!errorHolder.documentScope) {
1035
1083
  errorHolder.documentScope = [];
1036
1084
  }
1037
1085
 
1038
1086
  errorHolder.documentScope.push(message);
1039
- }
1040
- else {
1041
- if (! errorHolder.fieldScope) {
1087
+ } else {
1088
+ if (!errorHolder.fieldScope) {
1042
1089
  errorHolder.fieldScope = {};
1043
1090
  }
1044
1091
 
1045
1092
  let pointer = errorHolder.fieldScope;
1046
1093
 
1047
1094
  for (let i = 0; i < errorContext.length; i++) {
1048
- if (! pointer.children) {
1095
+ if (!pointer.children) {
1049
1096
  pointer.children = {};
1050
1097
  }
1051
1098
 
1052
- if (! has(pointer.children, errorContext[i])) {
1099
+ if (!has(pointer.children, errorContext[i])) {
1053
1100
  pointer.children[errorContext[i]] = {};
1054
1101
  }
1055
1102
  pointer = pointer.children[errorContext[i]];
1056
1103
  }
1057
1104
 
1058
- if (! has(pointer, 'messages')) {
1105
+ if (!has(pointer, "messages")) {
1059
1106
  pointer.messages = [];
1060
1107
  }
1061
1108
 
1062
1109
  pointer.messages.push(message);
1063
1110
  }
1064
- }
1065
- else if (errorContext === 'document') {
1066
- throw kerror.get('validation', 'check', 'failed_document', message);
1067
- }
1068
- else {
1111
+ } else if (errorContext === "document") {
1112
+ throw kerror.get("validation", "check", "failed_document", message);
1113
+ } else {
1069
1114
  throw kerror.get(
1070
- 'validation',
1071
- 'check',
1072
- 'failed_field',
1073
- errorContext.join('.'),
1074
- message);
1115
+ "validation",
1116
+ "check",
1117
+ "failed_field",
1118
+ errorContext.join("."),
1119
+ message
1120
+ );
1075
1121
  }
1076
1122
  }
1077
1123
 
@@ -1081,49 +1127,47 @@ function manageErrorMessage (errorContext, errorHolder, message, structured) {
1081
1127
  *
1082
1128
  * @returns {Promise}
1083
1129
  */
1084
- function getValidationConfiguration () {
1130
+ function getValidationConfiguration() {
1085
1131
  return global.kuzzle.internalIndex
1086
- .search('validations', {}, { from: 0, size: 1000 })
1087
- .then(result => {
1132
+ .search("validations", {}, { from: 0, size: 1000 })
1133
+ .then((result) => {
1088
1134
  let validation = {};
1089
1135
 
1090
- if ( result
1091
- && Array.isArray(result.hits)
1092
- && result.hits.length > 0
1093
- ) {
1136
+ if (result && Array.isArray(result.hits) && result.hits.length > 0) {
1094
1137
  for (const { _source, _id } of result.hits) {
1095
- const collectionName = `${_id.split('#')[0]}/${_id.split('#')[1]}`;
1138
+ const collectionName = `${_id.split("#")[0]}/${_id.split("#")[1]}`;
1096
1139
 
1097
- if (! get(_source, 'index')) {
1140
+ if (!get(_source, "index")) {
1098
1141
  throw assertionError.get(
1099
- 'incorrect_validation_format',
1142
+ "incorrect_validation_format",
1100
1143
  collectionName,
1101
- 'index');
1144
+ "index"
1145
+ );
1102
1146
  }
1103
1147
 
1104
- if (! get(_source, 'collection')) {
1148
+ if (!get(_source, "collection")) {
1105
1149
  throw assertionError.get(
1106
- 'incorrect_validation_format',
1150
+ "incorrect_validation_format",
1107
1151
  collectionName,
1108
- 'collection');
1152
+ "collection"
1153
+ );
1109
1154
  }
1110
1155
 
1111
- if (! get(_source, 'validation')) {
1156
+ if (!get(_source, "validation")) {
1112
1157
  throw assertionError.get(
1113
- 'incorrect_validation_format',
1158
+ "incorrect_validation_format",
1114
1159
  collectionName,
1115
- 'validation');
1160
+ "validation"
1161
+ );
1116
1162
  }
1117
1163
 
1118
- if (! has(validation, _source.index)) {
1164
+ if (!has(validation, _source.index)) {
1119
1165
  validation[_source.index] = {};
1120
1166
  }
1121
1167
 
1122
- validation[_source.index][_source.collection] =
1123
- _source.validation;
1168
+ validation[_source.index][_source.collection] = _source.validation;
1124
1169
  }
1125
- }
1126
- else if (global.kuzzle.config.validation) {
1170
+ } else if (global.kuzzle.config.validation) {
1127
1171
  // We can't wait prepareDb as it runs outside of the rest of the start
1128
1172
  validation = global.kuzzle.config.validation;
1129
1173
  }