kuzzle 2.16.11 → 2.17.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 (187) hide show
  1. package/lib/api/controllers/adminController.js +3 -3
  2. package/lib/api/controllers/authController.js +12 -12
  3. package/lib/api/controllers/baseController.js +60 -3
  4. package/lib/api/controllers/clusterController.js +1 -1
  5. package/lib/api/controllers/collectionController.js +7 -5
  6. package/lib/api/controllers/documentController.js +130 -17
  7. package/lib/api/controllers/indexController.js +1 -1
  8. package/lib/api/controllers/memoryStorageController.js +39 -38
  9. package/lib/api/controllers/realtimeController.js +1 -1
  10. package/lib/api/controllers/securityController.js +50 -50
  11. package/lib/api/controllers/serverController.js +73 -27
  12. package/lib/api/documentExtractor.js +3 -3
  13. package/lib/api/funnel.js +44 -21
  14. package/lib/api/httpRoutes.js +9 -4
  15. package/lib/api/openapi/OpenApiManager.d.ts +11 -0
  16. package/lib/api/openapi/OpenApiManager.js +96 -0
  17. package/lib/api/openapi/{document → components/document}/count.yaml +2 -2
  18. package/lib/api/openapi/{document → components/document}/create.yaml +2 -2
  19. package/lib/api/openapi/{document → components/document}/createOrReplace.yaml +2 -2
  20. package/lib/api/openapi/{document → components/document}/delete.yaml +1 -1
  21. package/lib/api/openapi/{document → components/document}/deleteByQuery.yaml +2 -2
  22. package/lib/api/openapi/{document → components/document}/exists.yaml +1 -1
  23. package/lib/api/openapi/{document → components/document}/get.yaml +1 -1
  24. package/lib/api/openapi/{document → components/document}/index.d.ts +2 -0
  25. package/lib/api/openapi/{document → components/document}/index.js +7 -2
  26. package/lib/api/openapi/{document → components/document}/replace.yaml +2 -2
  27. package/lib/api/openapi/{document → components/document}/scroll.yaml +1 -1
  28. package/lib/api/openapi/{document → components/document}/update.yaml +2 -2
  29. package/lib/api/openapi/components/document/validate.yaml +42 -0
  30. package/lib/api/openapi/components/index.d.ts +2 -0
  31. package/lib/api/openapi/components/index.js +18 -0
  32. package/lib/api/openapi/{payloads.yaml → components/payloads.yaml} +0 -0
  33. package/lib/api/openapi/index.d.ts +1 -2
  34. package/lib/api/openapi/index.js +1 -5
  35. package/lib/api/openapi/openApiGenerator.d.ts +7 -0
  36. package/lib/api/openapi/openApiGenerator.js +133 -0
  37. package/lib/api/request/kuzzleRequest.js +8 -6
  38. package/lib/cluster/node.js +9 -9
  39. package/lib/cluster/publisher.js +1 -1
  40. package/lib/cluster/state.js +20 -4
  41. package/lib/cluster/subscriber.js +1 -1
  42. package/lib/cluster/workers/IDCardRenewer.js +2 -2
  43. package/lib/config/default.config.js +1 -0
  44. package/lib/config/index.js +6 -6
  45. package/lib/core/auth/passportResponse.js +6 -6
  46. package/lib/core/auth/passportWrapper.js +5 -5
  47. package/lib/core/backend/backend.d.ts +11 -3
  48. package/lib/core/backend/backend.js +22 -17
  49. package/lib/core/backend/backendConfig.d.ts +5 -1
  50. package/lib/core/backend/backendConfig.js +25 -2
  51. package/lib/core/backend/backendController.js +21 -5
  52. package/lib/core/backend/backendErrors.d.ts +58 -0
  53. package/lib/core/backend/backendErrors.js +121 -0
  54. package/lib/core/backend/backendHook.js +21 -5
  55. package/lib/core/backend/backendImport.js +21 -5
  56. package/lib/core/backend/backendOpenApi.d.ts +9 -0
  57. package/lib/core/backend/backendOpenApi.js +69 -0
  58. package/lib/core/backend/backendPipe.js +21 -5
  59. package/lib/core/backend/backendPlugin.js +22 -3
  60. package/lib/core/backend/backendVault.js +21 -2
  61. package/lib/core/backend/index.d.ts +2 -0
  62. package/lib/core/backend/index.js +2 -0
  63. package/lib/core/network/accessLogger.js +6 -6
  64. package/lib/core/network/clientConnection.js +1 -1
  65. package/lib/core/network/entryPoint.js +5 -5
  66. package/lib/core/network/httpRouter/index.js +5 -5
  67. package/lib/core/network/httpRouter/routeHandler.js +3 -3
  68. package/lib/core/network/httpRouter/routePart.js +5 -5
  69. package/lib/core/network/protocolManifest.js +1 -1
  70. package/lib/core/network/protocols/httpMessage.js +2 -2
  71. package/lib/core/network/protocols/httpwsProtocol.js +228 -50
  72. package/lib/core/network/protocols/mqttProtocol.js +3 -3
  73. package/lib/core/network/protocols/protocol.js +3 -3
  74. package/lib/core/network/router.js +7 -6
  75. package/lib/core/plugin/plugin.js +38 -64
  76. package/lib/core/plugin/pluginContext.js +22 -3
  77. package/lib/core/plugin/pluginManifest.js +3 -3
  78. package/lib/core/plugin/pluginRepository.js +5 -5
  79. package/lib/core/plugin/pluginsManager.js +29 -28
  80. package/lib/core/realtime/channel.js +20 -4
  81. package/lib/core/realtime/hotelClerk.js +24 -5
  82. package/lib/core/realtime/notification/server.js +1 -1
  83. package/lib/core/realtime/notification/user.js +1 -1
  84. package/lib/core/realtime/notifier.js +5 -5
  85. package/lib/core/security/index.js +1 -1
  86. package/lib/core/security/profileRepository.d.ts +176 -0
  87. package/lib/core/security/profileRepository.js +445 -443
  88. package/lib/core/security/roleRepository.js +16 -16
  89. package/lib/core/security/securityLoader.js +2 -2
  90. package/lib/core/security/tokenRepository.js +11 -11
  91. package/lib/core/security/userRepository.js +8 -8
  92. package/lib/core/shared/abstractManifest.js +4 -4
  93. package/lib/core/shared/repository.js +5 -5
  94. package/lib/core/shared/sdk/embeddedSdk.js +21 -2
  95. package/lib/core/shared/sdk/funnelProtocol.js +1 -1
  96. package/lib/core/shared/sdk/impersonatedSdk.js +1 -1
  97. package/lib/core/shared/store.js +30 -23
  98. package/lib/core/statistics/statistics.js +17 -17
  99. package/lib/core/storage/clientAdapter.js +45 -10
  100. package/lib/core/storage/indexCache.js +20 -4
  101. package/lib/core/validation/baseType.js +5 -5
  102. package/lib/core/validation/types/anything.js +1 -1
  103. package/lib/core/validation/types/boolean.js +2 -2
  104. package/lib/core/validation/types/date.js +9 -9
  105. package/lib/core/validation/types/email.js +5 -5
  106. package/lib/core/validation/types/enum.js +6 -6
  107. package/lib/core/validation/types/geoPoint.js +2 -2
  108. package/lib/core/validation/types/geoShape.js +28 -25
  109. package/lib/core/validation/types/integer.js +4 -4
  110. package/lib/core/validation/types/ipAddress.js +7 -6
  111. package/lib/core/validation/types/numeric.js +4 -4
  112. package/lib/core/validation/types/object.js +5 -5
  113. package/lib/core/validation/types/string.js +5 -5
  114. package/lib/core/validation/types/url.js +7 -6
  115. package/lib/core/validation/validation.js +95 -84
  116. package/lib/kerror/codes/1-services.json +12 -0
  117. package/lib/kerror/codes/2-api.json +12 -0
  118. package/lib/kerror/codes/3-network.json +12 -0
  119. package/lib/kerror/codes/4-plugin.json +6 -0
  120. package/lib/kerror/codes/index.js +11 -11
  121. package/lib/kerror/errors/multipleErrorsError.d.ts +1 -1
  122. package/lib/kerror/errors/multipleErrorsError.js +3 -3
  123. package/lib/kerror/index.d.ts +82 -0
  124. package/lib/kerror/index.js +176 -143
  125. package/lib/kuzzle/dumpGenerator.js +3 -3
  126. package/lib/kuzzle/event/kuzzleEventEmitter.js +4 -4
  127. package/lib/kuzzle/event/pipeRunner.js +1 -1
  128. package/lib/kuzzle/event/waterfall.js +6 -6
  129. package/lib/kuzzle/kuzzle.js +59 -9
  130. package/lib/kuzzle/log.js +3 -3
  131. package/lib/kuzzle/vault.js +3 -3
  132. package/lib/model/security/profile.d.ts +54 -0
  133. package/lib/model/security/profile.js +192 -232
  134. package/lib/model/security/rights.js +1 -1
  135. package/lib/model/security/role.d.ts +40 -0
  136. package/lib/model/security/role.js +174 -190
  137. package/lib/model/security/user.d.ts +29 -0
  138. package/lib/model/security/user.js +103 -52
  139. package/lib/model/storage/apiKey.js +2 -2
  140. package/lib/model/storage/baseModel.js +3 -3
  141. package/lib/service/cache/redis.js +7 -7
  142. package/lib/service/storage/elasticsearch.js +152 -90
  143. package/lib/service/storage/esWrapper.js +2 -3
  144. package/lib/types/ControllerDefinition.d.ts +3 -3
  145. package/lib/types/ControllerRights.d.ts +22 -0
  146. package/lib/types/ControllerRights.js +23 -0
  147. package/lib/types/HttpStream.d.ts +32 -0
  148. package/lib/types/HttpStream.js +70 -0
  149. package/lib/types/OpenApiDefinition.d.ts +43 -0
  150. package/lib/types/{config/StorageService/StorageServiceElasticsearchConfiguration.js → OpenApiDefinition.js} +1 -1
  151. package/lib/types/Plugin.js +20 -4
  152. package/lib/types/Policy.d.ts +25 -0
  153. package/lib/types/{InternalLogger.js → Policy.js} +2 -2
  154. package/lib/types/PolicyRestrictions.d.ts +21 -0
  155. package/lib/types/PolicyRestrictions.js +23 -0
  156. package/lib/types/Target.d.ts +15 -0
  157. package/lib/types/Target.js +23 -0
  158. package/lib/types/config/KuzzleConfiguration.d.ts +4 -0
  159. package/lib/types/config/ServicesConfiguration.d.ts +2 -2
  160. package/lib/types/config/{StorageService/StorageServiceElasticsearchConfiguration.d.ts → storageEngine/StorageEngineElasticsearchConfiguration.d.ts} +10 -3
  161. package/lib/types/config/storageEngine/StorageEngineElasticsearchConfiguration.js +3 -0
  162. package/lib/types/errors/ErrorDefinition.d.ts +27 -0
  163. package/lib/types/errors/ErrorDefinition.js +3 -0
  164. package/lib/types/errors/ErrorDomains.d.ts +17 -0
  165. package/lib/types/errors/ErrorDomains.js +3 -0
  166. package/lib/types/index.d.ts +9 -1
  167. package/lib/types/index.js +9 -1
  168. package/lib/util/array.d.ts +11 -0
  169. package/lib/util/array.js +57 -0
  170. package/lib/util/assertType.js +6 -6
  171. package/lib/util/bufferedPassThrough.d.ts +76 -0
  172. package/lib/util/bufferedPassThrough.js +161 -0
  173. package/lib/util/deprecate.js +7 -5
  174. package/lib/util/didYouMean.js +1 -1
  175. package/lib/util/dump-collection.d.ts +3 -0
  176. package/lib/util/dump-collection.js +284 -0
  177. package/lib/util/extractFields.js +2 -2
  178. package/lib/util/inflector.d.ts +8 -0
  179. package/lib/util/inflector.js +16 -0
  180. package/lib/util/mutex.js +21 -2
  181. package/lib/util/requestAssertions.js +7 -7
  182. package/lib/util/wildcard.js +55 -0
  183. package/package-lock.json +535 -75
  184. package/package.json +5 -3
  185. package/lib/api/openApiGenerator.d.ts +0 -7
  186. package/lib/api/openApiGenerator.js +0 -197
  187. package/lib/types/InternalLogger.d.ts +0 -25
@@ -36,7 +36,7 @@ const assertionError = kerror.wrap('validation', 'assert');
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,7 +55,7 @@ class Validation {
55
55
  /**
56
56
  * Walks through all types in "defaultTypesFiles" initializes all types
57
57
  */
58
- init() {
58
+ init () {
59
59
  [
60
60
  'anything',
61
61
  'boolean',
@@ -123,7 +123,8 @@ class Validation {
123
123
  collectionSpec.strict,
124
124
  errorMessages,
125
125
  verbose);
126
- } catch (error) {
126
+ }
127
+ catch (error) {
127
128
  // The strictness message can be received here only if it happens at
128
129
  // the validation of the document's root
129
130
  if (error.message !== 'strictness') {
@@ -153,7 +154,7 @@ class Validation {
153
154
  }
154
155
  }
155
156
 
156
- if (!verbose) {
157
+ if (! verbose) {
157
158
  // We only modify the request if the validation succeeds
158
159
  if (collectionSpec.fields && collectionSpec.fields.children) {
159
160
  request.input.body = this.recurseApplyDefault(
@@ -165,7 +166,7 @@ class Validation {
165
166
  return request;
166
167
  }
167
168
 
168
- return {errorMessages, valid: isValid};
169
+ return { errorMessages, valid: isValid };
169
170
  }
170
171
 
171
172
  /**
@@ -173,7 +174,7 @@ class Validation {
173
174
  * @param {*} documentSubset
174
175
  * @param {...StructuredFieldSpecification} collectionSpecSubset
175
176
  */
176
- recurseApplyDefault(isUpdate, documentSubset, collectionSpecSubset) {
177
+ recurseApplyDefault (isUpdate, documentSubset, collectionSpecSubset) {
177
178
  Object.keys(collectionSpecSubset).forEach(fieldName => {
178
179
  const
179
180
  specSubset = collectionSpecSubset[fieldName],
@@ -189,14 +190,16 @@ class Validation {
189
190
  field[i],
190
191
  specSubset.children);
191
192
  }
192
- } else {
193
+ }
194
+ else {
193
195
  documentSubset[fieldName] = this.recurseApplyDefault(
194
196
  isUpdate,
195
197
  field,
196
198
  specSubset.children);
197
199
  }
198
- } else if (specSubset.defaultValue
199
- && (field === null || (!isUpdate && !has(documentSubset, fieldName)))
200
+ }
201
+ else if (specSubset.defaultValue
202
+ && (field === null || (! isUpdate && ! has(documentSubset, fieldName)))
200
203
  ) {
201
204
  documentSubset[fieldName] = specSubset.defaultValue;
202
205
  }
@@ -212,7 +215,7 @@ class Validation {
212
215
  * @param {string[]} errorMessages
213
216
  * @param {boolean} verbose
214
217
  */
215
- recurseFieldValidation(
218
+ recurseFieldValidation (
216
219
  documentSubset,
217
220
  collectionSpecSubset,
218
221
  strictness,
@@ -221,7 +224,7 @@ class Validation {
221
224
  ) {
222
225
  if (strictness) {
223
226
  for (const field of Object.keys(documentSubset)) {
224
- if (!collectionSpecSubset[field]) {
227
+ if (! collectionSpecSubset[field]) {
225
228
  const error = new Error('strictness');
226
229
  error.details = { field };
227
230
  throw error;
@@ -229,7 +232,7 @@ class Validation {
229
232
  }
230
233
  }
231
234
 
232
- if (!verbose) {
235
+ if (! verbose) {
233
236
  // We stop as soon as one field is not valid
234
237
  return Object.keys(collectionSpecSubset).every(fieldName =>
235
238
  this.isValidField(
@@ -262,7 +265,7 @@ class Validation {
262
265
  * @param {boolean} verbose
263
266
  * @returns {boolean}
264
267
  */
265
- isValidField(
268
+ isValidField (
266
269
  fieldName,
267
270
  documentSubset,
268
271
  collectionSpecSubset,
@@ -275,7 +278,7 @@ class Validation {
275
278
  let result = true;
276
279
 
277
280
  if (field.mandatory
278
- && !has(field, 'defaultValue')
281
+ && ! has(field, 'defaultValue')
279
282
  && _.isNil(documentSubset[fieldName])
280
283
  ) {
281
284
  manageErrorMessage(
@@ -286,13 +289,13 @@ class Validation {
286
289
  return false;
287
290
  }
288
291
 
289
- if (!_.isNil(documentSubset[fieldName])) {
292
+ if (! _.isNil(documentSubset[fieldName])) {
290
293
  let
291
294
  nestedStrictness = false,
292
295
  fieldValues;
293
296
 
294
297
  if (field.multivalued.value) {
295
- if (!Array.isArray(documentSubset[fieldName])) {
298
+ if (! Array.isArray(documentSubset[fieldName])) {
296
299
  manageErrorMessage(
297
300
  field.path,
298
301
  errorMessages,
@@ -324,7 +327,8 @@ class Validation {
324
327
  }
325
328
 
326
329
  fieldValues = documentSubset[fieldName];
327
- } else {
330
+ }
331
+ else {
328
332
  if (Array.isArray(documentSubset[fieldName])) {
329
333
  manageErrorMessage(
330
334
  field.path,
@@ -346,7 +350,7 @@ class Validation {
346
350
  for (const val of fieldValues) {
347
351
  const fieldErrors = [];
348
352
 
349
- if (!this.types[field.type].validate(
353
+ if (! this.types[field.type].validate(
350
354
  field.typeOptions,
351
355
  val,
352
356
  fieldErrors)
@@ -358,7 +362,8 @@ class Validation {
358
362
  errorMessages,
359
363
  'An error has occurred during validation.',
360
364
  verbose);
361
- } else {
365
+ }
366
+ else {
362
367
  fieldErrors.forEach(
363
368
  message => manageErrorMessage(
364
369
  field.path,
@@ -371,7 +376,7 @@ class Validation {
371
376
 
372
377
  if (this.types[field.type].allowChildren && field.children) {
373
378
  try {
374
- if (!this.recurseFieldValidation(
379
+ if (! this.recurseFieldValidation(
375
380
  val,
376
381
  field.children,
377
382
  nestedStrictness,
@@ -380,20 +385,23 @@ class Validation {
380
385
  )) {
381
386
  result = false;
382
387
  }
383
- } catch (error) {
388
+ }
389
+ catch (error) {
384
390
  if (error.message === 'strictness') {
385
391
  manageErrorMessage(
386
392
  field.path,
387
393
  errorMessages,
388
394
  `The field is set to "strict"; cannot add unspecified sub-field "${error.details.field}".`,
389
395
  verbose);
390
- } else if (verbose) {
396
+ }
397
+ else if (verbose) {
391
398
  manageErrorMessage(
392
399
  field.path,
393
400
  errorMessages,
394
401
  error.message,
395
402
  verbose);
396
- } else {
403
+ }
404
+ else {
397
405
  throw error;
398
406
  }
399
407
 
@@ -408,7 +416,7 @@ class Validation {
408
416
  /**
409
417
  * @returns {Promise.<T>}
410
418
  */
411
- curateSpecification() {
419
+ curateSpecification () {
412
420
  const
413
421
  promises = [],
414
422
  specification = {};
@@ -428,7 +436,7 @@ class Validation {
428
436
  )
429
437
  .then(curatedSpec => {
430
438
 
431
- if (!has(specification, indexName)) {
439
+ if (! has(specification, indexName)) {
432
440
  specification[indexName] = {};
433
441
  }
434
442
 
@@ -462,7 +470,7 @@ class Validation {
462
470
  * @param {boolean} [verboseErrors]
463
471
  * @returns {Promise<object>}
464
472
  */
465
- validateFormat(
473
+ validateFormat (
466
474
  indexName,
467
475
  collectionName,
468
476
  collectionSpec,
@@ -481,11 +489,11 @@ class Validation {
481
489
  if (verboseErrors && result.isValid === false) {
482
490
  return result;
483
491
  }
484
- return {isValid: true};
492
+ return { isValid: true };
485
493
  })
486
494
  // we do not want to reject since this method goal is
487
495
  // to know what is going wrong with the given spec
488
- .catch(error => ({errors: [error], isValid: false}));
496
+ .catch(error => ({ errors: [error], isValid: false }));
489
497
  }
490
498
 
491
499
  /**
@@ -497,7 +505,7 @@ class Validation {
497
505
  * @returns {Promise<CollectionSpecification>}
498
506
  * @rejects PreconditionError
499
507
  */
500
- async curateCollectionSpecification(
508
+ async curateCollectionSpecification (
501
509
  index,
502
510
  collection,
503
511
  spec,
@@ -512,14 +520,14 @@ class Validation {
512
520
  };
513
521
  const allowed = ['strict', 'fields', 'validators'];
514
522
 
515
- if (!checkAllowedProperties(spec, allowed)) {
523
+ if (! checkAllowedProperties(spec, allowed)) {
516
524
  error = assertionError.get(
517
525
  'unexpected_properties',
518
526
  `${index}.${collection}`,
519
527
  allowed.join(', '));
520
528
 
521
529
  if (verbose) {
522
- return {errors: [error.message], isValid: false};
530
+ return { errors: [error.message], isValid: false };
523
531
  }
524
532
 
525
533
  throw error;
@@ -553,7 +561,7 @@ class Validation {
553
561
 
554
562
  processed.validators = filterId;
555
563
  }
556
- catch(e) {
564
+ catch (e) {
557
565
  global.kuzzle.log.error(e);
558
566
  throw assertionError.getFrom(e, 'invalid_filters', e.message);
559
567
  }
@@ -562,7 +570,7 @@ class Validation {
562
570
  return processed;
563
571
  }
564
572
 
565
- structureCollectionValidation(
573
+ structureCollectionValidation (
566
574
  collectionSpec,
567
575
  indexName,
568
576
  collectionName,
@@ -600,20 +608,21 @@ class Validation {
600
608
  maxDepth = field.depth;
601
609
  }
602
610
 
603
- if (!fields[field.depth]) {
611
+ if (! fields[field.depth]) {
604
612
  fields[field.depth] = [];
605
613
  }
606
614
 
607
615
  fields[field.depth].push(field);
608
616
  }
609
- } catch (error) {
617
+ }
618
+ catch (error) {
610
619
  global.kuzzle.log.error(error);
611
620
  throwOrStoreError(error, verboseErrors, errors);
612
621
  }
613
622
  }
614
623
 
615
624
  if (errors.length > 0) {
616
- return {errors, isValid: false};
625
+ return { errors, isValid: false };
617
626
  }
618
627
 
619
628
  if (Object.keys(fields).length > 0) {
@@ -631,7 +640,7 @@ class Validation {
631
640
  * @returns {object}
632
641
  * @throws PreconditionError
633
642
  */
634
- curateFieldSpecification(
643
+ curateFieldSpecification (
635
644
  fieldSpec,
636
645
  indexName,
637
646
  collectionName,
@@ -659,13 +668,13 @@ class Validation {
659
668
  }
660
669
  });
661
670
 
662
- if (!has(fieldSpec, 'typeOptions')) {
671
+ if (! has(fieldSpec, 'typeOptions')) {
663
672
  fieldSpec.typeOptions = {};
664
673
  }
665
674
 
666
675
  const allowed = this.types[fieldSpec.type].allowedTypeOptions || [];
667
676
 
668
- if (!checkAllowedProperties(fieldSpec.typeOptions, allowed)) {
677
+ if (! checkAllowedProperties(fieldSpec.typeOptions, allowed)) {
669
678
  throwOrStoreError(
670
679
  assertionError.get(
671
680
  'unexpected_properties',
@@ -678,8 +687,9 @@ class Validation {
678
687
  try {
679
688
  fieldSpec.typeOptions = this.types[fieldSpec.type]
680
689
  .validateFieldSpecification(fieldSpec.typeOptions);
681
- } catch (e) {
682
- if (!verboseErrors) {
690
+ }
691
+ catch (e) {
692
+ if (! verboseErrors) {
683
693
  if (e instanceof KuzzleError) {
684
694
  throw e;
685
695
  }
@@ -695,7 +705,7 @@ class Validation {
695
705
  }
696
706
 
697
707
  if (errors.length > 0) {
698
- return {errors, isValid: false};
708
+ return { errors, isValid: false };
699
709
  }
700
710
 
701
711
  debug(
@@ -705,7 +715,7 @@ class Validation {
705
715
  fieldName,
706
716
  fieldSpec);
707
717
 
708
- return {fieldSpec, isValid: true};
718
+ return { fieldSpec, isValid: true };
709
719
  }
710
720
 
711
721
  /**
@@ -717,7 +727,7 @@ class Validation {
717
727
  * @returns {object}
718
728
  * @throws PreconditionError
719
729
  */
720
- curateFieldSpecificationFormat(
730
+ curateFieldSpecificationFormat (
721
731
  fieldSpec,
722
732
  indexName,
723
733
  collectionName,
@@ -735,7 +745,7 @@ class Validation {
735
745
  'typeOptions'
736
746
  ];
737
747
 
738
- if (!checkAllowedProperties(fieldSpec, props)) {
748
+ if (! checkAllowedProperties(fieldSpec, props)) {
739
749
  throwOrStoreError(
740
750
  assertionError.get(
741
751
  'unexpected_properties',
@@ -745,7 +755,7 @@ class Validation {
745
755
  errors);
746
756
  }
747
757
 
748
- if (!has(fieldSpec, 'type')) {
758
+ if (! has(fieldSpec, 'type')) {
749
759
  throwOrStoreError(
750
760
  assertionError.get(
751
761
  'missing_type',
@@ -754,7 +764,7 @@ class Validation {
754
764
  errors);
755
765
  }
756
766
 
757
- if (!has(this.types, fieldSpec.type)) {
767
+ if (! has(this.types, fieldSpec.type)) {
758
768
  throwOrStoreError(
759
769
  assertionError.get(
760
770
  'unknown_type',
@@ -766,7 +776,7 @@ class Validation {
766
776
 
767
777
  if (has(fieldSpec, 'multivalued')) {
768
778
  const multivaluedProps = ['value', 'minCount', 'maxCount'];
769
- if (!checkAllowedProperties(fieldSpec.multivalued, multivaluedProps)) {
779
+ if (! checkAllowedProperties(fieldSpec.multivalued, multivaluedProps)) {
770
780
  throwOrStoreError(
771
781
  assertionError.get(
772
782
  'unexpected_properties',
@@ -776,7 +786,7 @@ class Validation {
776
786
  errors);
777
787
  }
778
788
 
779
- if (!has(fieldSpec.multivalued, 'value')) {
789
+ if (! has(fieldSpec.multivalued, 'value')) {
780
790
  throwOrStoreError(
781
791
  assertionError.get(
782
792
  'missing_value',
@@ -796,7 +806,7 @@ class Validation {
796
806
  }
797
807
 
798
808
  for (const unexpected of ['minCount', 'maxCount']) {
799
- if ( !fieldSpec.multivalued.value
809
+ if ( ! fieldSpec.multivalued.value
800
810
  && has(fieldSpec.multivalued, unexpected)
801
811
  ) {
802
812
  throwOrStoreError(
@@ -825,10 +835,10 @@ class Validation {
825
835
  }
826
836
 
827
837
  if (errors.length > 0) {
828
- return {errors, isValid: false};
838
+ return { errors, isValid: false };
829
839
  }
830
840
 
831
- return {isValid: true};
841
+ return { isValid: true };
832
842
  }
833
843
 
834
844
  /**
@@ -838,7 +848,7 @@ class Validation {
838
848
  * @param {boolean} dryRun
839
849
  * @returns {string}
840
850
  */
841
- curateValidatorFilter(indexName, collectionName, validatorFilter, dryRun) {
851
+ curateValidatorFilter (indexName, collectionName, validatorFilter, dryRun) {
842
852
  const query = {
843
853
  bool: {
844
854
  must: validatorFilter
@@ -847,7 +857,7 @@ class Validation {
847
857
 
848
858
  this.koncorde.validate(query);
849
859
 
850
- if (!dryRun) {
860
+ if (! dryRun) {
851
861
  debug(
852
862
  'Registering filter validator %s/%s: %O',
853
863
  indexName,
@@ -866,12 +876,12 @@ class Validation {
866
876
  * @param {ValidationType} validationType
867
877
  * @throws {PluginImplementationError}
868
878
  */
869
- addType(validationType) {
870
- if (!validationType.typeName) {
879
+ addType (validationType) {
880
+ if (! validationType.typeName) {
871
881
  throw kerror.get('validation', 'types', 'missing_type_name');
872
882
  }
873
883
 
874
- if ( !validationType.validate
884
+ if ( ! validationType.validate
875
885
  || typeof validationType.validate !== 'function'
876
886
  ) {
877
887
  throw kerror.get(
@@ -882,7 +892,7 @@ class Validation {
882
892
  'validate');
883
893
  }
884
894
 
885
- if ( !validationType.validateFieldSpecification
895
+ if ( ! validationType.validateFieldSpecification
886
896
  || typeof validationType.validateFieldSpecification !== 'function'
887
897
  ) {
888
898
  throw kerror.get(
@@ -896,7 +906,7 @@ class Validation {
896
906
  if (has(validationType, 'allowChildren')
897
907
  && validationType.allowChildren
898
908
  ) {
899
- if (!validationType.getStrictness
909
+ if (! validationType.getStrictness
900
910
  || typeof validationType.getStrictness !== 'function'
901
911
  ) {
902
912
  throw kerror.get(
@@ -928,13 +938,13 @@ class Validation {
928
938
  * @param {string[]} allowedProperties
929
939
  * @returns {boolean}
930
940
  */
931
- function checkAllowedProperties(object, allowedProperties) {
932
- if (!isPlainObject(object)) {
941
+ function checkAllowedProperties (object, allowedProperties) {
942
+ if (! isPlainObject(object)) {
933
943
  return false;
934
944
  }
935
945
 
936
- return !Object.keys(object).some(
937
- propertyName => !allowedProperties.includes(propertyName));
946
+ return ! Object.keys(object).some(
947
+ propertyName => ! allowedProperties.includes(propertyName));
938
948
  }
939
949
 
940
950
  /**
@@ -943,7 +953,7 @@ function checkAllowedProperties(object, allowedProperties) {
943
953
  * @param {number} maxDepth : depth of the fields; counting starts at 1
944
954
  * @throws PreconditionError
945
955
  */
946
- function curateStructuredFields(typeAllowsChildren, fields, maxDepth) {
956
+ function curateStructuredFields (typeAllowsChildren, fields, maxDepth) {
947
957
  const
948
958
  /** @type StructuredFieldSpecification */
949
959
  structuredFields = {
@@ -952,7 +962,7 @@ function curateStructuredFields(typeAllowsChildren, fields, maxDepth) {
952
962
  };
953
963
 
954
964
  for (let i = 1; i <= maxDepth; i++) {
955
- if (!has(fields, i)) {
965
+ if (! has(fields, i)) {
956
966
  throw assertionError.get('missing_nested_spec');
957
967
  }
958
968
 
@@ -961,11 +971,11 @@ function curateStructuredFields(typeAllowsChildren, fields, maxDepth) {
961
971
  parent = getParent(structuredFields, field.path),
962
972
  childKey = field.path[field.path.length - 1];
963
973
 
964
- if (!parent.root && typeAllowsChildren.indexOf(parent.type) === -1) {
974
+ if (! parent.root && typeAllowsChildren.indexOf(parent.type) === -1) {
965
975
  throw assertionError.get('unexpected_children', parent.type);
966
976
  }
967
977
 
968
- if (!has(parent, 'children')) {
978
+ if (! has(parent, 'children')) {
969
979
  parent.children = {};
970
980
  }
971
981
 
@@ -981,7 +991,7 @@ function curateStructuredFields(typeAllowsChildren, fields, maxDepth) {
981
991
  * @param {string[]}fieldPath
982
992
  * @returns {StructuredFieldSpecification}
983
993
  */
984
- function getParent(structuredFields, fieldPath) {
994
+ function getParent (structuredFields, fieldPath) {
985
995
  if (fieldPath.length === 1) {
986
996
  return structuredFields;
987
997
  }
@@ -989,7 +999,7 @@ function getParent(structuredFields, fieldPath) {
989
999
  let pointer = structuredFields;
990
1000
 
991
1001
  for (let i = 0; i < fieldPath.length - 1; i++) {
992
- if (!has(pointer.children, fieldPath[i])) {
1002
+ if (! has(pointer.children, fieldPath[i])) {
993
1003
  throw assertionError.get('missing_parent', fieldPath.join('.'));
994
1004
  }
995
1005
 
@@ -1004,8 +1014,8 @@ function getParent(structuredFields, fieldPath) {
1004
1014
  * @param {boolean} doNotThrow
1005
1015
  * @param {string[]} errors
1006
1016
  */
1007
- function throwOrStoreError(error, doNotThrow, errorMessages) {
1008
- if (!doNotThrow) {
1017
+ function throwOrStoreError (error, doNotThrow, errorMessages) {
1018
+ if (! doNotThrow) {
1009
1019
  throw error;
1010
1020
  }
1011
1021
 
@@ -1018,33 +1028,34 @@ function throwOrStoreError(error, doNotThrow, errorMessages) {
1018
1028
  * @param {string} message
1019
1029
  * @param {boolean} structured
1020
1030
  */
1021
- function manageErrorMessage(errorContext, errorHolder, message, structured) {
1031
+ function manageErrorMessage (errorContext, errorHolder, message, structured) {
1022
1032
  if (structured) {
1023
1033
  if (errorContext === 'document') {
1024
- if (!errorHolder.documentScope) {
1034
+ if (! errorHolder.documentScope) {
1025
1035
  errorHolder.documentScope = [];
1026
1036
  }
1027
1037
 
1028
1038
  errorHolder.documentScope.push(message);
1029
- } else {
1030
- if (!errorHolder.fieldScope) {
1039
+ }
1040
+ else {
1041
+ if (! errorHolder.fieldScope) {
1031
1042
  errorHolder.fieldScope = {};
1032
1043
  }
1033
1044
 
1034
1045
  let pointer = errorHolder.fieldScope;
1035
1046
 
1036
1047
  for (let i = 0; i < errorContext.length; i++) {
1037
- if (!pointer.children) {
1048
+ if (! pointer.children) {
1038
1049
  pointer.children = {};
1039
1050
  }
1040
1051
 
1041
- if (!has(pointer.children, errorContext[i])) {
1052
+ if (! has(pointer.children, errorContext[i])) {
1042
1053
  pointer.children[errorContext[i]] = {};
1043
1054
  }
1044
1055
  pointer = pointer.children[errorContext[i]];
1045
1056
  }
1046
1057
 
1047
- if (!has(pointer, 'messages')) {
1058
+ if (! has(pointer, 'messages')) {
1048
1059
  pointer.messages = [];
1049
1060
  }
1050
1061
 
@@ -1070,9 +1081,9 @@ function manageErrorMessage(errorContext, errorHolder, message, structured) {
1070
1081
  *
1071
1082
  * @returns {Promise}
1072
1083
  */
1073
- function getValidationConfiguration() {
1084
+ function getValidationConfiguration () {
1074
1085
  return global.kuzzle.internalIndex
1075
- .search('validations', {}, {from: 0, size: 1000})
1086
+ .search('validations', {}, { from: 0, size: 1000 })
1076
1087
  .then(result => {
1077
1088
  let validation = {};
1078
1089
 
@@ -1083,28 +1094,28 @@ function getValidationConfiguration() {
1083
1094
  for (const { _source, _id } of result.hits) {
1084
1095
  const collectionName = `${_id.split('#')[0]}/${_id.split('#')[1]}`;
1085
1096
 
1086
- if (!get(_source, 'index')) {
1097
+ if (! get(_source, 'index')) {
1087
1098
  throw assertionError.get(
1088
1099
  'incorrect_validation_format',
1089
1100
  collectionName,
1090
1101
  'index');
1091
1102
  }
1092
1103
 
1093
- if (!get(_source, 'collection')) {
1104
+ if (! get(_source, 'collection')) {
1094
1105
  throw assertionError.get(
1095
1106
  'incorrect_validation_format',
1096
1107
  collectionName,
1097
1108
  'collection');
1098
1109
  }
1099
1110
 
1100
- if (!get(_source, 'validation')) {
1111
+ if (! get(_source, 'validation')) {
1101
1112
  throw assertionError.get(
1102
1113
  'incorrect_validation_format',
1103
1114
  collectionName,
1104
1115
  'validation');
1105
1116
  }
1106
1117
 
1107
- if (!has(validation, _source.index)) {
1118
+ if (! has(validation, _source.index)) {
1108
1119
  validation[_source.index] = {};
1109
1120
  }
1110
1121
 
@@ -275,6 +275,18 @@
275
275
  "code": 48,
276
276
  "message": "An \"%s\" is not allowed to be associated with multiple \"%\". This is probably not linked to this request but rather the consequence of previous actions on ElasticSearch.",
277
277
  "class": "PreconditionError"
278
+ },
279
+ "invalid_multi_index_collection_usage": {
280
+ "description": "Searches on multiple collections should be achieved with the \"targets\" argument who contains list of indexes and collections to search within.",
281
+ "message": "Searches on multiple collections should be achieved with the \"targets\" argument who contains list of indexes and collections to search within.",
282
+ "code": 49,
283
+ "class": "BadRequestError"
284
+ },
285
+ "invalid_target_format": {
286
+ "description": "When a target index or collections contains invalid characters used for multi index search or \"_all\"",
287
+ "message": "The %s (\"%s\") contains invalid characters \",+*\" or is equal to \"_all\" which is forbidden",
288
+ "code": 50,
289
+ "class": "BadRequestError"
278
290
  }
279
291
  }
280
292
  },
@@ -87,6 +87,18 @@
87
87
  "code": 14,
88
88
  "message": "%s",
89
89
  "class": "BadRequestError"
90
+ },
91
+ "forbidden_stream": {
92
+ "description": "A forbidden HttpStream has been provided in a response",
93
+ "code": 15,
94
+ "message": "Cannot set an HttpStream as a request's response in a non-http protocol",
95
+ "class": "InternalError"
96
+ },
97
+ "unsupported_protocol": {
98
+ "description": "A request has been made with an unsupported protocol",
99
+ "code": 16,
100
+ "message": "The protocol \"%s\" is not supported by the API action \"%s\".",
101
+ "class": "InternalError"
90
102
  }
91
103
  }
92
104
  },
@@ -81,6 +81,18 @@
81
81
  "code": 13,
82
82
  "message": "Maximum HTTP file size exceeded",
83
83
  "class": "SizeLimitError"
84
+ },
85
+ "stream_closed": {
86
+ "description": "The stream has been closed or destroyed before sending the response",
87
+ "code": 14,
88
+ "message": "Stream closed or destroyed.",
89
+ "class": "InternalError"
90
+ },
91
+ "stream_errored": {
92
+ "description": "The stream is errored",
93
+ "code": 15,
94
+ "message": "Stream errored: %s",
95
+ "class": "InternalError"
84
96
  }
85
97
  }
86
98
  },