kuzzle 2.16.8 → 2.17.0

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 (167) hide show
  1. package/README.md +11 -0
  2. package/lib/api/controllers/adminController.js +7 -6
  3. package/lib/api/controllers/authController.js +11 -11
  4. package/lib/api/controllers/baseController.js +60 -3
  5. package/lib/api/controllers/clusterController.js +1 -1
  6. package/lib/api/controllers/collectionController.js +7 -5
  7. package/lib/api/controllers/documentController.js +130 -17
  8. package/lib/api/controllers/indexController.js +1 -1
  9. package/lib/api/controllers/memoryStorageController.js +39 -38
  10. package/lib/api/controllers/realtimeController.js +1 -1
  11. package/lib/api/controllers/securityController.js +49 -49
  12. package/lib/api/controllers/serverController.js +73 -27
  13. package/lib/api/documentExtractor.js +3 -3
  14. package/lib/api/funnel.js +40 -21
  15. package/lib/api/httpRoutes.js +9 -4
  16. package/lib/api/openapi/OpenApiManager.d.ts +11 -0
  17. package/lib/api/openapi/OpenApiManager.js +96 -0
  18. package/lib/api/openapi/{document → components/document}/count.yaml +2 -2
  19. package/lib/api/openapi/{document → components/document}/create.yaml +2 -2
  20. package/lib/api/openapi/{document → components/document}/createOrReplace.yaml +2 -2
  21. package/lib/api/openapi/{document → components/document}/delete.yaml +1 -1
  22. package/lib/api/openapi/{document → components/document}/deleteByQuery.yaml +2 -2
  23. package/lib/api/openapi/{document → components/document}/exists.yaml +1 -1
  24. package/lib/api/openapi/{document → components/document}/get.yaml +1 -1
  25. package/lib/api/openapi/{document → components/document}/index.d.ts +2 -0
  26. package/lib/api/openapi/{document → components/document}/index.js +7 -2
  27. package/lib/api/openapi/{document → components/document}/replace.yaml +2 -2
  28. package/lib/api/openapi/{document → components/document}/scroll.yaml +1 -1
  29. package/lib/api/openapi/{document → components/document}/update.yaml +2 -2
  30. package/lib/api/openapi/components/document/validate.yaml +42 -0
  31. package/lib/api/openapi/components/index.d.ts +2 -0
  32. package/lib/api/openapi/components/index.js +18 -0
  33. package/lib/api/openapi/{payloads.yaml → components/payloads.yaml} +0 -0
  34. package/lib/api/openapi/index.d.ts +1 -2
  35. package/lib/api/openapi/index.js +1 -5
  36. package/lib/api/openapi/openApiGenerator.d.ts +7 -0
  37. package/lib/api/openapi/openApiGenerator.js +133 -0
  38. package/lib/api/request/kuzzleRequest.d.ts +11 -11
  39. package/lib/api/request/kuzzleRequest.js +38 -48
  40. package/lib/cluster/node.js +9 -9
  41. package/lib/cluster/publisher.js +1 -1
  42. package/lib/cluster/subscriber.js +1 -1
  43. package/lib/cluster/workers/IDCardRenewer.js +13 -4
  44. package/lib/config/default.config.js +1 -0
  45. package/lib/config/index.js +6 -6
  46. package/lib/core/auth/passportResponse.js +6 -6
  47. package/lib/core/auth/passportWrapper.js +5 -5
  48. package/lib/core/backend/backend.d.ts +5 -1
  49. package/lib/core/backend/backend.js +12 -8
  50. package/lib/core/backend/backendConfig.d.ts +5 -1
  51. package/lib/core/backend/backendConfig.js +4 -0
  52. package/lib/core/backend/backendOpenApi.d.ts +9 -0
  53. package/lib/core/backend/backendOpenApi.js +69 -0
  54. package/lib/core/backend/index.d.ts +1 -0
  55. package/lib/core/backend/index.js +1 -0
  56. package/lib/core/network/accessLogger.js +6 -6
  57. package/lib/core/network/clientConnection.js +1 -1
  58. package/lib/core/network/entryPoint.js +5 -5
  59. package/lib/core/network/httpRouter/index.js +5 -5
  60. package/lib/core/network/httpRouter/routeHandler.js +3 -3
  61. package/lib/core/network/httpRouter/routePart.js +5 -5
  62. package/lib/core/network/protocolManifest.js +1 -1
  63. package/lib/core/network/protocols/httpMessage.js +2 -2
  64. package/lib/core/network/protocols/httpwsProtocol.js +207 -46
  65. package/lib/core/network/protocols/mqttProtocol.js +3 -3
  66. package/lib/core/network/protocols/protocol.js +3 -3
  67. package/lib/core/network/router.js +7 -6
  68. package/lib/core/plugin/plugin.js +38 -64
  69. package/lib/core/plugin/pluginContext.d.ts +10 -1
  70. package/lib/core/plugin/pluginContext.js +2 -0
  71. package/lib/core/plugin/pluginManifest.js +3 -3
  72. package/lib/core/plugin/pluginRepository.js +5 -5
  73. package/lib/core/plugin/pluginsManager.js +29 -28
  74. package/lib/core/realtime/notification/server.js +1 -1
  75. package/lib/core/realtime/notification/user.js +1 -1
  76. package/lib/core/realtime/notifier.js +5 -5
  77. package/lib/core/security/index.js +1 -1
  78. package/lib/core/security/profileRepository.d.ts +176 -0
  79. package/lib/core/security/profileRepository.js +426 -443
  80. package/lib/core/security/roleRepository.js +16 -16
  81. package/lib/core/security/securityLoader.js +3 -3
  82. package/lib/core/security/tokenRepository.js +18 -21
  83. package/lib/core/security/userRepository.js +8 -8
  84. package/lib/core/shared/abstractManifest.js +4 -4
  85. package/lib/core/shared/repository.js +6 -6
  86. package/lib/core/shared/sdk/funnelProtocol.js +1 -1
  87. package/lib/core/shared/sdk/impersonatedSdk.js +1 -1
  88. package/lib/core/shared/store.js +30 -23
  89. package/lib/core/statistics/statistics.js +17 -17
  90. package/lib/core/storage/clientAdapter.js +45 -10
  91. package/lib/core/validation/baseType.js +5 -5
  92. package/lib/core/validation/types/anything.js +1 -1
  93. package/lib/core/validation/types/boolean.js +2 -2
  94. package/lib/core/validation/types/date.js +9 -9
  95. package/lib/core/validation/types/email.js +5 -5
  96. package/lib/core/validation/types/enum.js +6 -6
  97. package/lib/core/validation/types/geoPoint.js +2 -2
  98. package/lib/core/validation/types/geoShape.js +28 -25
  99. package/lib/core/validation/types/integer.js +4 -4
  100. package/lib/core/validation/types/ipAddress.js +7 -6
  101. package/lib/core/validation/types/numeric.js +4 -4
  102. package/lib/core/validation/types/object.js +5 -5
  103. package/lib/core/validation/types/string.js +5 -5
  104. package/lib/core/validation/types/url.js +7 -6
  105. package/lib/core/validation/validation.js +95 -84
  106. package/lib/kerror/codes/1-services.json +12 -0
  107. package/lib/kerror/codes/2-api.json +12 -0
  108. package/lib/kerror/codes/3-network.json +12 -0
  109. package/lib/kerror/codes/4-plugin.json +6 -0
  110. package/lib/kerror/codes/index.js +11 -11
  111. package/lib/kerror/index.js +1 -1
  112. package/lib/kuzzle/dumpGenerator.js +3 -3
  113. package/lib/kuzzle/event/kuzzleEventEmitter.js +4 -4
  114. package/lib/kuzzle/event/pipeRunner.js +1 -1
  115. package/lib/kuzzle/event/waterfall.js +6 -6
  116. package/lib/kuzzle/kuzzle.js +36 -5
  117. package/lib/kuzzle/log.js +3 -3
  118. package/lib/kuzzle/vault.js +3 -3
  119. package/lib/model/security/profile.d.ts +54 -0
  120. package/lib/model/security/profile.js +174 -233
  121. package/lib/model/security/rights.js +1 -1
  122. package/lib/model/security/role.d.ts +40 -0
  123. package/lib/model/security/role.js +159 -191
  124. package/lib/model/security/user.d.ts +29 -0
  125. package/lib/model/security/user.js +84 -52
  126. package/lib/model/storage/apiKey.js +2 -2
  127. package/lib/model/storage/baseModel.js +3 -3
  128. package/lib/service/cache/redis.js +7 -7
  129. package/lib/service/storage/elasticsearch.js +152 -90
  130. package/lib/service/storage/esWrapper.js +2 -3
  131. package/lib/types/ControllerDefinition.d.ts +3 -3
  132. package/lib/types/ControllerRights.d.ts +22 -0
  133. package/lib/types/ControllerRights.js +23 -0
  134. package/lib/types/HttpStream.d.ts +32 -0
  135. package/lib/types/HttpStream.js +70 -0
  136. package/lib/types/OpenApiDefinition.d.ts +43 -0
  137. package/lib/types/{config/StorageService/StorageServiceElasticsearchConfiguration.js → OpenApiDefinition.js} +1 -1
  138. package/lib/types/Policy.d.ts +25 -0
  139. package/lib/types/Policy.js +23 -0
  140. package/lib/types/PolicyRestrictions.d.ts +21 -0
  141. package/lib/types/PolicyRestrictions.js +23 -0
  142. package/lib/types/Target.d.ts +15 -0
  143. package/lib/types/Target.js +23 -0
  144. package/lib/types/config/KuzzleConfiguration.d.ts +4 -0
  145. package/lib/types/config/ServicesConfiguration.d.ts +2 -2
  146. package/lib/types/config/{StorageService/StorageServiceElasticsearchConfiguration.d.ts → storageEngine/StorageEngineElasticsearchConfiguration.d.ts} +10 -3
  147. package/lib/types/config/storageEngine/StorageEngineElasticsearchConfiguration.js +3 -0
  148. package/lib/types/index.d.ts +7 -1
  149. package/lib/types/index.js +7 -1
  150. package/lib/util/array.d.ts +11 -0
  151. package/lib/util/array.js +57 -0
  152. package/lib/util/assertType.js +6 -6
  153. package/lib/util/bufferedPassThrough.d.ts +76 -0
  154. package/lib/util/bufferedPassThrough.js +161 -0
  155. package/lib/util/deprecate.js +7 -5
  156. package/lib/util/didYouMean.js +1 -1
  157. package/lib/util/dump-collection.d.ts +3 -0
  158. package/lib/util/dump-collection.js +265 -0
  159. package/lib/util/extractFields.js +2 -2
  160. package/lib/util/inflector.d.ts +8 -0
  161. package/lib/util/inflector.js +16 -0
  162. package/lib/util/requestAssertions.js +7 -7
  163. package/lib/util/wildcard.js +55 -0
  164. package/package-lock.json +881 -431
  165. package/package.json +23 -20
  166. package/lib/api/openApiGenerator.d.ts +0 -7
  167. package/lib/api/openApiGenerator.js +0 -197
@@ -0,0 +1,161 @@
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.BufferedPassThrough = void 0;
27
+ const stream_1 = __importDefault(require("stream"));
28
+ /**
29
+ * This streams accumulate chunks data into a buffer until the amount of data is equal or exceed the buffer size.
30
+ * Then, it emits a single chunk with the accumulated data.
31
+ *
32
+ * This stream is useful when you want to reduce the amount of chunk produced by a stream.
33
+ * This can helps reducing the number of syscall made by the stream consumer.
34
+ */
35
+ class BufferedPassThrough extends stream_1.default.Duplex {
36
+ constructor(options = { highWaterMark: 8196 }) {
37
+ super(options);
38
+ this.bufferSize = options.highWaterMark;
39
+ this.buffer = Buffer.alloc(options.highWaterMark);
40
+ this.offset = 0;
41
+ }
42
+ /**
43
+ * Writes a string or buffer to the internal buffer starting at the internal buffer offset.
44
+ * Data will be copied from the given start to the end position.
45
+ *
46
+ * @param data
47
+ * @param start Where to start copying/writing data from
48
+ * @param end Where to end copying/writing data from
49
+ * @param encoding Type of encoding to use
50
+ * @returns How many bytes have been copied / written to the internal buffer.
51
+ */
52
+ writeToBuffer(data, start, end, encoding) {
53
+ if (encoding === 'buffer') {
54
+ return data.copy(this.buffer, this.offset, start, end);
55
+ }
56
+ if (start === 0 && end === data.length) {
57
+ return this.buffer.write(data, this.offset, end - start, encoding);
58
+ }
59
+ return this.buffer.write(data.slice(start, end), this.offset, end - start, encoding);
60
+ }
61
+ async writeChunks(chunks) {
62
+ for (const chunk of chunks) {
63
+ await this.writeChunkData(chunk.chunk, chunk.encoding);
64
+ }
65
+ }
66
+ /**
67
+ * Writes a chunk of data to the internal buffer.
68
+ * If the internal buffer is full, it will be pushed to the stream.
69
+ * @param chunk
70
+ * @param encoding
71
+ */
72
+ async writeChunkData(chunk, encoding) {
73
+ let chunkOffset = 0;
74
+ while (chunkOffset < chunk.length) {
75
+ const remainingChunkSize = chunk.length - chunkOffset;
76
+ const remainingBufferSize = this.bufferSize - this.offset;
77
+ // If the remaining bytes in the chunk exceed the remaining bytes in the internal buffer
78
+ if (remainingChunkSize >= remainingBufferSize) {
79
+ // Write as much as the remaining bytes as possible to the buffer from t
80
+ chunkOffset += this.writeToBuffer(chunk, chunkOffset, chunkOffset + remainingBufferSize, encoding);
81
+ // Sends the whole buffer to the stream since it is full
82
+ if (!this.push(this.buffer)) {
83
+ await new Promise(res => {
84
+ this.once('_drained', res);
85
+ });
86
+ }
87
+ this.offset = 0; // Reset the offset
88
+ }
89
+ else {
90
+ // Write the whole chunk to the buffer
91
+ const size = this.writeToBuffer(chunk, chunkOffset, chunk.length, encoding);
92
+ // Increase the internal buffer offset
93
+ this.offset += size;
94
+ break;
95
+ }
96
+ }
97
+ }
98
+ /**
99
+ * @override from stream.Duplex
100
+ * Internal method called when data needs to be written.
101
+ * @param chunkData
102
+ * @param encoding
103
+ * @param callback
104
+ */
105
+ _write(chunkData, encoding, callback) {
106
+ this.writeChunkData(chunkData, encoding).then(() => {
107
+ callback();
108
+ });
109
+ }
110
+ /**
111
+ * @override from stream.Duplex
112
+ * Internal method called when multiple chunks were stored and needs to be written.
113
+ * @param chunks
114
+ * @param callback
115
+ */
116
+ _writev(chunks, callback) {
117
+ this.writeChunks(chunks).then(() => {
118
+ callback();
119
+ });
120
+ }
121
+ /**
122
+ * @override from stream.Duplex
123
+ * Internal method called when the stream is drained, to resume pushing data.
124
+ * @param size
125
+ */
126
+ _read() {
127
+ // Emits an internal _drained event when the internal buffer is drained.
128
+ this.emit('_drained');
129
+ }
130
+ /**
131
+ * @override from stream.Duplex
132
+ * Internal method called when the stream is ended.
133
+ * @param callback
134
+ */
135
+ _final(callback) {
136
+ if (this.buffer && this.offset > 0) {
137
+ // Push last bit of data
138
+ this.push(this.buffer.slice(0, this.offset));
139
+ }
140
+ this.push(null); // Close the stream
141
+ this.buffer = null;
142
+ callback();
143
+ }
144
+ /**
145
+ * @override from stream.Duplex
146
+ * Internal method called when stream is destroyed.
147
+ * @param err
148
+ * @param callback
149
+ */
150
+ _destroy(err, callback) {
151
+ if (this.buffer && this.offset > 0) {
152
+ // Push last bit of data
153
+ this.push(this.buffer.slice(0, this.offset));
154
+ }
155
+ this.push(null); // Close the stream
156
+ this.buffer = null;
157
+ callback(err);
158
+ }
159
+ }
160
+ exports.BufferedPassThrough = BufferedPassThrough;
161
+ //# sourceMappingURL=bufferedPassThrough.js.map
@@ -35,15 +35,17 @@ const warnIfDeprecated = (logger, deprecations, member) => {
35
35
  .find(deprecated => deprecated === member),
36
36
  alternative = deprecations[deprecatedProperty];
37
37
 
38
- if (!deprecatedProperty) {
38
+ if (! deprecatedProperty) {
39
39
  return;
40
40
  }
41
41
 
42
42
  if (alternative && typeof alternative.message === 'string') {
43
43
  deprecationWarning(logger, alternative.message);
44
- } else if (typeof alternative === 'string') {
44
+ }
45
+ else if (typeof alternative === 'string') {
45
46
  deprecationWarning(logger, `Use of '${deprecatedProperty}' property is deprecated. Please, use '${alternative}' instead.`);
46
- } else {
47
+ }
48
+ else {
47
49
  deprecationWarning(logger, `Use of '${deprecatedProperty}' property is deprecated.`);
48
50
  }
49
51
  };
@@ -54,7 +56,7 @@ const deprecateProperties = (logger, target, deprecations = {}) => {
54
56
  }
55
57
 
56
58
  return new Proxy(target, {
57
- get(object, key, ...rest) {
59
+ get (object, key, ...rest) {
58
60
  if (key === '__isProxy') {
59
61
  return true;
60
62
  }
@@ -64,7 +66,7 @@ const deprecateProperties = (logger, target, deprecations = {}) => {
64
66
  return Reflect.get(object, key, ...rest);
65
67
  },
66
68
 
67
- set(object, key, ...rest) {
69
+ set (object, key, ...rest) {
68
70
  warnIfDeprecated(logger, deprecations, key);
69
71
 
70
72
  return Reflect.set(object, key, ...rest);
@@ -23,7 +23,7 @@
23
23
 
24
24
  const didYouMean = require('didyoumean');
25
25
 
26
- function printDidYouMean(...args) {
26
+ function printDidYouMean (...args) {
27
27
  if (global.NODE_ENV !== 'development') {
28
28
  return '';
29
29
  }
@@ -0,0 +1,3 @@
1
+ import { JSONObject } from '../../index';
2
+ import { HttpStream } from '../types';
3
+ export declare function dumpCollectionDocuments(index: string, collection: string, query?: any, format?: string, fields?: string[], options?: JSONObject): HttpStream;
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.dumpCollectionDocuments = void 0;
7
+ const ndjson_1 = __importDefault(require("ndjson"));
8
+ const get_1 = __importDefault(require("lodash/get"));
9
+ const isObject_1 = __importDefault(require("lodash/isObject"));
10
+ const kerror_1 = __importDefault(require("../kerror"));
11
+ const bufferedPassThrough_1 = require("./bufferedPassThrough");
12
+ const types_1 = require("../types");
13
+ /**
14
+ * Flatten an object transform:
15
+ * {
16
+ * title: "kuzzle",
17
+ * info : {
18
+ * tag: "news"
19
+ * }
20
+ * }
21
+ *
22
+ * Into an object like:
23
+ * {
24
+ * title: "kuzzle",
25
+ * info.tag: news
26
+ * }
27
+ *
28
+ * @param {Object} target the object we have to flatten
29
+ * @returns {Object} the flattened object
30
+ */
31
+ function flattenObject(target) {
32
+ const output = {};
33
+ flattenStep(output, target);
34
+ return output;
35
+ }
36
+ function flattenStep(output, object, prev = null) {
37
+ const keys = Object.keys(object);
38
+ for (let i = 0; i < keys.length; i++) {
39
+ const key = keys[i];
40
+ const value = object[key];
41
+ const newKey = prev ? prev + '.' + key : key;
42
+ if (Object.prototype.toString.call(value) === '[object Object]') {
43
+ output[newKey] = value;
44
+ flattenStep(output, value, newKey);
45
+ }
46
+ output[newKey] = value;
47
+ }
48
+ }
49
+ /**
50
+ * Extract fields from mapping by removing the properties from es mapping
51
+ *
52
+ * @param mapping
53
+ * @returns
54
+ */
55
+ function extractMappingFields(mapping) {
56
+ const newMapping = {};
57
+ for (const key of Object.keys(mapping)) {
58
+ if (key === 'properties' && (0, isObject_1.default)(mapping[key])) {
59
+ newMapping[key] = extractMappingFields(mapping[key]);
60
+ }
61
+ else if ((0, isObject_1.default)(mapping[key]) && mapping[key].type) {
62
+ newMapping[key] = mapping[key].type;
63
+ }
64
+ else {
65
+ newMapping[key] = mapping[key];
66
+ }
67
+ }
68
+ return newMapping;
69
+ }
70
+ /**
71
+ * An iteration-order-safe version of lodash.values
72
+ *
73
+ * @param object The object containing the values
74
+ * @param fields The field names to pick in the right order
75
+ * @returns The values in the same order as the fields
76
+ * @see https://lodash.com/docs/4.17.15#values
77
+ */
78
+ function pickValues(object, fields) {
79
+ return fields.map(f => formatValueForCSV((0, get_1.default)(object, f)));
80
+ }
81
+ /**
82
+ * Formats the value for correct CSV output, avoiding to return
83
+ * values that would badly serialize in CSV.
84
+ *
85
+ * @param value The value to format
86
+ * @returns The value or a string telling the value is not scalar
87
+ */
88
+ function formatValueForCSV(value) {
89
+ if ((0, isObject_1.default)(value)) {
90
+ return '[OBJECT]';
91
+ }
92
+ return value;
93
+ }
94
+ class AbstractDumper {
95
+ constructor(index, collection, query = {}, writeStream, options = {
96
+ fieldsName: {},
97
+ scroll: '5s',
98
+ separator: ',',
99
+ size: 10,
100
+ }) {
101
+ this.index = index;
102
+ this.collection = collection;
103
+ this.query = query;
104
+ this.writeStream = writeStream;
105
+ this.options = options;
106
+ if (!writeStream) {
107
+ throw kerror_1.default.get('api', 'assert', 'missing_argument', 'writeStream');
108
+ }
109
+ }
110
+ /**
111
+ * One-shot call before the dump. Can be used to
112
+ * perform setup operations before dumping.
113
+ *
114
+ * @returns void
115
+ */
116
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
117
+ async setup() { }
118
+ /**
119
+ * One-shot call before iterating over the data. Can be
120
+ * used to write the header of the dumped output.
121
+ */
122
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
123
+ async writeHeader() { }
124
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
125
+ async tearDown() { }
126
+ async scroll(scrollId) {
127
+ if (!scrollId) {
128
+ return null;
129
+ }
130
+ try {
131
+ return await global.kuzzle.ask('core:storage:public:document:scroll', scrollId, { scrollTTL: this.options.scroll });
132
+ }
133
+ catch {
134
+ return null;
135
+ }
136
+ }
137
+ /**
138
+ * The loop that iterates over the documents of the collection and
139
+ * calls all the other hooks.
140
+ *
141
+ * @returns a promise resolving when the dump is finished.
142
+ */
143
+ async dump() {
144
+ const waitWrite = new Promise((resolve, reject) => this.writeStream ? this.writeStream.on('finish', resolve) : reject());
145
+ this.writeStream.on('error', error => {
146
+ throw error;
147
+ });
148
+ await this.setup();
149
+ await this.writeHeader();
150
+ let results = await global.kuzzle.ask('core:storage:public:document:search', this.index, this.collection, this.query, {
151
+ lang: this.options.lang,
152
+ scroll: this.options.scroll,
153
+ size: this.options.size,
154
+ });
155
+ do {
156
+ for (const hit of results.hits) {
157
+ await this.onResult({
158
+ _id: hit._id,
159
+ _source: hit._source
160
+ });
161
+ }
162
+ } while ((results = await this.scroll(results.scrollId)));
163
+ await this.tearDown();
164
+ this.writeStream.end();
165
+ return waitWrite;
166
+ }
167
+ }
168
+ class JSONLDumper extends AbstractDumper {
169
+ constructor() {
170
+ super(...arguments);
171
+ this.ndjsonStream = ndjson_1.default.stringify();
172
+ }
173
+ async setup() {
174
+ this.ndjsonStream.on('data', (line) => {
175
+ this.writeStream.write(line);
176
+ });
177
+ }
178
+ async writeHeader() {
179
+ await this.writeLine({
180
+ collection: this.collection,
181
+ index: this.index,
182
+ type: 'collection',
183
+ });
184
+ }
185
+ writeLine(content) {
186
+ return new Promise(resolve => {
187
+ if (this.ndjsonStream.write(content)) {
188
+ resolve();
189
+ }
190
+ else {
191
+ this.ndjsonStream.once('drain', resolve);
192
+ }
193
+ });
194
+ }
195
+ onResult(document) {
196
+ return this.writeLine({
197
+ _id: document._id,
198
+ body: document._source,
199
+ });
200
+ }
201
+ get fileExtension() {
202
+ return 'jsonl';
203
+ }
204
+ }
205
+ class CSVDumper extends AbstractDumper {
206
+ constructor(index, collection, query = {}, writeStream, options, fields) {
207
+ super(index, collection, query, writeStream, options);
208
+ this.fields = fields;
209
+ }
210
+ get fileExtension() {
211
+ return 'csv';
212
+ }
213
+ async setup() {
214
+ if (!this.fields.length) {
215
+ // If no field has been selected, then all fields are selected.
216
+ const mappings = await global.kuzzle.ask('core:storage:public:mappings:get', this.index, this.collection);
217
+ if (!mappings.properties) {
218
+ return;
219
+ }
220
+ this.fields = Object.keys(flattenObject(extractMappingFields(mappings.properties)));
221
+ }
222
+ else if (this.fields.includes('_id')) {
223
+ // Delete '_id' from the selected fields, since IDs are
224
+ // _always_ exported.
225
+ this.fields.splice(this.fields.indexOf('_id'), 1);
226
+ }
227
+ }
228
+ writeHeader() {
229
+ const mappedFieldsName = ['_id', ...this.fields].map(field => {
230
+ return this.options.fieldsName[field] || field;
231
+ });
232
+ return this.writeLine(mappedFieldsName.join(this.options.separator));
233
+ }
234
+ writeLine(content) {
235
+ return new Promise(resolve => {
236
+ if (this.writeStream.write(`${content}\n`)) {
237
+ resolve();
238
+ }
239
+ else {
240
+ this.writeStream.once('drain', resolve);
241
+ }
242
+ });
243
+ }
244
+ onResult(document) {
245
+ const values = [document._id, ...pickValues(document._source, this.fields)];
246
+ return this.writeLine(values.join(this.options.separator));
247
+ }
248
+ }
249
+ function dumpCollectionDocuments(index, collection, query = {}, format = 'jsonl', fields = [], options = {}) {
250
+ let dumper;
251
+ const writableStream = new bufferedPassThrough_1.BufferedPassThrough({ highWaterMark: 16384 });
252
+ switch (format.toLowerCase()) {
253
+ case 'csv':
254
+ dumper = new CSVDumper(index, collection, query, writableStream, options, fields);
255
+ dumper.dump();
256
+ break;
257
+ default:
258
+ dumper = new JSONLDumper(index, collection, query, writableStream, options);
259
+ dumper.dump();
260
+ break;
261
+ }
262
+ return new types_1.HttpStream(writableStream);
263
+ }
264
+ exports.dumpCollectionDocuments = dumpCollectionDocuments;
265
+ //# sourceMappingURL=dump-collection.js.map
@@ -32,7 +32,7 @@ const { isPlainObject } = require('./safeObject');
32
32
  *
33
33
  * @returns { Array<String> | Array<{ key: String, value: any }> }
34
34
  */
35
- function extractFields(document, {
35
+ function extractFields (document, {
36
36
  fieldsToIgnore = [],
37
37
  alsoExtractValues = false,
38
38
  } = {}, {
@@ -54,7 +54,7 @@ function extractFields(document, {
54
54
  { extractedFields, path: currentPath });
55
55
  }
56
56
  else if (alsoExtractValues) {
57
- extractedFields.push({key: currentPath, value});
57
+ extractedFields.push({ key: currentPath, value });
58
58
  }
59
59
  else {
60
60
  extractedFields.push(currentPath);
@@ -14,4 +14,12 @@ export declare class Inflector {
14
14
  * @param string String to transform the first letter in uppercase
15
15
  */
16
16
  static upFirst(string: string): string;
17
+ /**
18
+ * Converts a string to PascalCase
19
+ */
20
+ static pascalCase(string: string): string;
21
+ /**
22
+ * Converts a string to camelCase
23
+ */
24
+ static camelCase(string: any): string;
17
25
  }
@@ -19,8 +19,12 @@
19
19
  * See the License for the specific language governing permissions and
20
20
  * limitations under the License.
21
21
  */
22
+ var __importDefault = (this && this.__importDefault) || function (mod) {
23
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
+ };
22
25
  Object.defineProperty(exports, "__esModule", { value: true });
23
26
  exports.Inflector = void 0;
27
+ const lodash_1 = __importDefault(require("lodash"));
24
28
  class Inflector {
25
29
  /**
26
30
  * Converts a string to kebab-case
@@ -46,6 +50,18 @@ class Inflector {
46
50
  static upFirst(string) {
47
51
  return string.charAt(0).toUpperCase() + string.slice(1);
48
52
  }
53
+ /**
54
+ * Converts a string to PascalCase
55
+ */
56
+ static pascalCase(string) {
57
+ return lodash_1.default.startCase(string).replace(/ /g, '');
58
+ }
59
+ /**
60
+ * Converts a string to camelCase
61
+ */
62
+ static camelCase(string) {
63
+ return lodash_1.default.camelCase(string);
64
+ }
49
65
  }
50
66
  exports.Inflector = Inflector;
51
67
  //# sourceMappingURL=inflector.js.map
@@ -44,7 +44,7 @@ module.exports = {
44
44
  * @param {string} attribute
45
45
  */
46
46
  assertBodyAttributeType: (request, attribute, type) => {
47
- switch(type) {
47
+ switch (type) {
48
48
  case 'number':
49
49
  case 'boolean':
50
50
  case 'string':
@@ -86,7 +86,7 @@ module.exports = {
86
86
  * @param {string} attribute
87
87
  */
88
88
  assertBodyHasNotAttribute: (request, attribute) => {
89
- if (!_.isNil(get(request.input.body, attribute))) {
89
+ if (! _.isNil(get(request.input.body, attribute))) {
90
90
  throw assertionError.get('forbidden_argument', `body.${attribute}`);
91
91
  }
92
92
  },
@@ -108,7 +108,7 @@ module.exports = {
108
108
  * @param {Request} request
109
109
  */
110
110
  assertHasId: request => {
111
- if (!request.input.args._id) {
111
+ if (! request.input.args._id) {
112
112
  throw assertionError.get('missing_argument', '_id');
113
113
  }
114
114
  },
@@ -117,7 +117,7 @@ module.exports = {
117
117
  * @param {Request} request
118
118
  */
119
119
  assertHasIndex: request => {
120
- if (!request.input.args.index) {
120
+ if (! request.input.args.index) {
121
121
  throw assertionError.get('missing_argument', 'index');
122
122
  }
123
123
  },
@@ -126,11 +126,11 @@ module.exports = {
126
126
  * @param {Request} request
127
127
  */
128
128
  assertHasIndexAndCollection: request => {
129
- if (!request.input.args.index) {
129
+ if (! request.input.args.index) {
130
130
  throw assertionError.get('missing_argument', 'index');
131
131
  }
132
132
 
133
- if (!request.input.args.collection) {
133
+ if (! request.input.args.collection) {
134
134
  throw assertionError.get('missing_argument', 'collection');
135
135
  }
136
136
  },
@@ -150,7 +150,7 @@ module.exports = {
150
150
  * @param {Request} request
151
151
  */
152
152
  assertIsObject: value => {
153
- if (!isPlainObject(value)) {
153
+ if (! isPlainObject(value)) {
154
154
  throw assertionError.get('invalid_argument', value, 'object');
155
155
  }
156
156
  }
@@ -0,0 +1,55 @@
1
+ /*
2
+ * Kuzzle, a backend software, self-hostable and ready to use
3
+ * to power modern apps
4
+ *
5
+ * Copyright 2015-2020 Kuzzle
6
+ * mailto: support AT kuzzle.io
7
+ * website: http://kuzzle.io
8
+ *
9
+ * Licensed under the Apache License, Version 2.0 (the "License");
10
+ * you may not use this file except in compliance with the License.
11
+ * You may obtain a copy of the License at
12
+ *
13
+ * https://www.apache.org/licenses/LICENSE-2.0
14
+ *
15
+ * Unless required by applicable law or agreed to in writing, software
16
+ * distributed under the License is distributed on an "AS IS" BASIS,
17
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ * See the License for the specific language governing permissions and
19
+ * limitations under the License.
20
+ */
21
+
22
+ 'use strict';
23
+
24
+ const _ = require('lodash');
25
+
26
+ function match (pattern, list) {
27
+ // Match everything
28
+ if (pattern === '*') {
29
+ return list;
30
+ }
31
+ /**
32
+ * Reduces repeating "*" to one ".*"
33
+ * One of the fastest and most readable way to do this
34
+ */
35
+ const wildCardPattern = pattern.split('*')
36
+ .filter((patternPart, index, array) =>
37
+ patternPart !== ''
38
+ || index === 0
39
+ || index === array.length - 1
40
+ )
41
+ .map(patternPart => _.escapeRegExp(patternPart)) // escape special regex characters
42
+ .join('.*');
43
+
44
+ // Match everything
45
+ if (wildCardPattern === '.*') {
46
+ return list;
47
+ }
48
+
49
+ const regex = new RegExp(`^${wildCardPattern}$`);
50
+
51
+ // Keep only matching elements
52
+ return list.filter(item => ! regex.test(item));
53
+ }
54
+
55
+ module.exports = { match };