kourou 0.19.2 → 0.20.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 (53) hide show
  1. package/README.md +148 -108
  2. package/lib/commands/app/scaffold.d.ts +2 -0
  3. package/lib/commands/app/scaffold.js +30 -7
  4. package/lib/commands/app/start-services.js +7 -7
  5. package/lib/commands/collection/export.d.ts +1 -0
  6. package/lib/commands/collection/export.js +24 -7
  7. package/lib/commands/collection/import.js +4 -4
  8. package/lib/commands/config/diff.js +5 -5
  9. package/lib/commands/document/search.js +1 -1
  10. package/lib/commands/es/migrate.js +3 -3
  11. package/lib/commands/file/decrypt.js +2 -2
  12. package/lib/commands/file/encrypt.js +2 -2
  13. package/lib/commands/file/test.js +2 -2
  14. package/lib/commands/import.js +7 -7
  15. package/lib/commands/index/export.d.ts +2 -0
  16. package/lib/commands/index/export.js +13 -5
  17. package/lib/commands/index/import.js +4 -4
  18. package/lib/commands/instance/kill.js +6 -6
  19. package/lib/commands/instance/list.js +1 -1
  20. package/lib/commands/instance/logs.js +3 -3
  21. package/lib/commands/instance/spawn.js +10 -10
  22. package/lib/commands/profile/export.js +2 -2
  23. package/lib/commands/profile/import.js +2 -2
  24. package/lib/commands/realtime/subscribe.js +1 -1
  25. package/lib/commands/role/export.js +2 -3
  26. package/lib/commands/role/import.js +2 -2
  27. package/lib/commands/sdk/execute.js +2 -2
  28. package/lib/commands/sdk/query.js +1 -1
  29. package/lib/commands/user/export-mappings.js +2 -2
  30. package/lib/commands/user/export.js +4 -4
  31. package/lib/commands/user/import-mappings.js +1 -1
  32. package/lib/commands/user/import.js +2 -2
  33. package/lib/commands/vault/add.js +2 -2
  34. package/lib/commands/vault/decrypt.js +2 -2
  35. package/lib/commands/vault/encrypt.js +2 -2
  36. package/lib/commands/vault/show.js +3 -3
  37. package/lib/commands/vault/test.js +1 -1
  38. package/lib/common.d.ts +17 -0
  39. package/lib/common.js +35 -4
  40. package/lib/hooks/command_not_found/api-action.js +2 -2
  41. package/lib/support/dump-collection.d.ts +1 -1
  42. package/lib/support/dump-collection.js +211 -61
  43. package/lib/support/editor.js +3 -3
  44. package/lib/support/execute.js +1 -1
  45. package/lib/support/kuzzle.d.ts +1 -1
  46. package/lib/support/kuzzle.js +1 -0
  47. package/lib/support/restore-collection.js +5 -5
  48. package/lib/support/restore-securities.js +2 -2
  49. package/oclif.manifest.json +1 -1
  50. package/package.json +21 -19
  51. package/templates.tgz +0 -0
  52. package/lib/commands/es/snapshot/restore.d.ts +0 -18
  53. package/lib/commands/es/snapshot/restore.js +0 -52
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- const chalk_1 = tslib_1.__importDefault(require("chalk"));
5
- const query_1 = tslib_1.__importDefault(require("../../commands/sdk/query"));
4
+ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
5
+ const query_1 = (0, tslib_1.__importDefault)(require("../../commands/sdk/query"));
6
6
  /**
7
7
  * Hooks that run the corresponding API action with sdk:query.
8
8
  *
@@ -1,2 +1,2 @@
1
- export declare function dumpCollectionData(sdk: any, index: string, collection: string, batchSize: number, destPath: string, query?: any, format?: string): Promise<unknown>;
1
+ export declare function dumpCollectionData(sdk: any, index: string, collection: string, batchSize: number, destPath: string, query?: any, format?: string, fields?: string[]): Promise<void>;
2
2
  export declare function dumpCollectionMappings(sdk: any, index: string, collection: string, destPath: string, format?: string): Promise<void>;
@@ -2,76 +2,226 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.dumpCollectionMappings = exports.dumpCollectionData = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const fs_1 = tslib_1.__importDefault(require("fs"));
6
- const path_1 = tslib_1.__importDefault(require("path"));
7
- const cli_ux_1 = tslib_1.__importDefault(require("cli-ux"));
8
- const ndjson_1 = tslib_1.__importDefault(require("ndjson"));
9
- async function dumpCollectionData(sdk, index, collection, batchSize, destPath, query = {}, format = 'jsonl') {
10
- const collectionDir = path_1.default.join(destPath, collection);
11
- const filename = path_1.default.join(collectionDir, (format.toLowerCase() === 'jsonl' ? 'documents.jsonl' : 'documents.json'));
12
- const writeStream = fs_1.default.createWriteStream(filename);
13
- const waitWrite = new Promise(resolve => writeStream.on('finish', resolve));
14
- const ndjsonStream = ndjson_1.default.stringify();
15
- const options = {
16
- scroll: '1m',
17
- size: batchSize
18
- };
19
- const writeLine = (content) => {
5
+ const fs_1 = (0, tslib_1.__importDefault)(require("fs"));
6
+ const path_1 = (0, tslib_1.__importDefault)(require("path"));
7
+ const cli_ux_1 = (0, tslib_1.__importDefault)(require("cli-ux"));
8
+ const ndjson_1 = (0, tslib_1.__importDefault)(require("ndjson"));
9
+ const common_1 = require("../common");
10
+ /**
11
+ * Flatten an object transform:
12
+ * {
13
+ * title: "kuzzle",
14
+ * info : {
15
+ * tag: "news"
16
+ * }
17
+ * }
18
+ *
19
+ * Into an object like:
20
+ * {
21
+ * title: "kuzzle",
22
+ * info.tag: news
23
+ * }
24
+ *
25
+ * @param {Object} target the object we have to flatten
26
+ * @returns {Object} the flattened object
27
+ */
28
+ function flattenObject(target) {
29
+ const output = {};
30
+ flattenStep(output, target);
31
+ return output;
32
+ }
33
+ function flattenStep(output, object, prev = null) {
34
+ const keys = Object.keys(object);
35
+ for (let i = 0; i < keys.length; i++) {
36
+ const key = keys[i];
37
+ const value = object[key];
38
+ const newKey = prev ? prev + '.' + key : key;
39
+ if (Object.prototype.toString.call(value) === '[object Object]') {
40
+ output[newKey] = value;
41
+ flattenStep(output, value, newKey);
42
+ }
43
+ output[newKey] = value;
44
+ }
45
+ }
46
+ class AbstractDumper {
47
+ constructor(sdk, index, collection, batchSize, destPath, query = {}) {
48
+ this.sdk = sdk;
49
+ this.index = index;
50
+ this.collection = collection;
51
+ this.batchSize = batchSize;
52
+ this.destPath = destPath;
53
+ this.query = query;
54
+ this.collectionDir = path_1.default.join(this.destPath, this.collection);
55
+ this.options = {
56
+ scroll: '2s',
57
+ size: batchSize
58
+ };
59
+ }
60
+ /**
61
+ * One-shot call before the dump. Can be used to
62
+ * perform setup operations before dumping.
63
+ *
64
+ * @returns void
65
+ */
66
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
67
+ async setup() { }
68
+ /**
69
+ * One-shot call before iterating over the data. Can be
70
+ * used to write the header of the dumped output.
71
+ */
72
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
73
+ async writeHeader() { }
74
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
75
+ async tearDown() { }
76
+ /**
77
+ * The loop that iterates over the documents of the collection and
78
+ * calls all the other hooks.
79
+ *
80
+ * @returns a promise resolving when the dump is finished.
81
+ */
82
+ async dump() {
83
+ this.filename = path_1.default.join(this.collectionDir, `documents.${this.fileExtension}`);
84
+ this.writeStream = fs_1.default.createWriteStream(this.filename);
85
+ const waitWrite = new Promise((resolve, reject) => this.writeStream ? this.writeStream.on('finish', resolve) : reject());
86
+ this.writeStream.on('error', error => {
87
+ throw error;
88
+ });
89
+ await this.setup();
90
+ await this.writeHeader();
91
+ let results = await this.sdk.document.search(this.index, this.collection, { query: this.query }, this.options);
92
+ const progressBar = cli_ux_1.default.progress({
93
+ format: `Dumping ${this.collection} |{bar}| {percentage}% || {value}/{total} documents`
94
+ });
95
+ progressBar.start(results.total, 0);
96
+ do {
97
+ progressBar.update(results.fetched);
98
+ for (const hit of results.hits) {
99
+ await this.onResult({
100
+ _id: hit._id,
101
+ _source: hit._source
102
+ });
103
+ }
104
+ } while ((results = await results.next()));
105
+ await this.tearDown();
106
+ progressBar.stop();
107
+ this.writeStream.end();
108
+ return waitWrite;
109
+ }
110
+ }
111
+ class JSONLDumper extends AbstractDumper {
112
+ constructor() {
113
+ super(...arguments);
114
+ this.ndjsonStream = ndjson_1.default.stringify();
115
+ }
116
+ async setup() {
117
+ this.ndjsonStream.on('data', (line) => {
118
+ if (!this.writeStream) {
119
+ throw new Error('Cannot write data: WriteStream is not initialized.');
120
+ }
121
+ this.writeStream.write(line);
122
+ });
123
+ return;
124
+ }
125
+ async writeHeader() {
126
+ await this.writeLine({ type: 'collection', index: this.index, collection: this.collection });
127
+ }
128
+ writeLine(content) {
20
129
  return new Promise(resolve => {
21
- if (ndjsonStream.write(content)) {
130
+ if (this.ndjsonStream.write(content)) {
22
131
  resolve(undefined);
23
132
  }
24
133
  else {
25
- ndjsonStream.once('drain', resolve);
134
+ this.ndjsonStream.once('drain', resolve);
26
135
  }
27
136
  });
28
- };
29
- writeStream.on('error', error => {
30
- throw error;
31
- });
32
- ndjsonStream.on('data', (line) => writeStream.write(line));
33
- fs_1.default.mkdirSync(collectionDir, { recursive: true });
34
- if (format.toLowerCase() === 'jsonl') {
35
- await writeLine({ type: 'collection', index, collection });
36
- }
37
- let results = await sdk.document.search(index, collection, { query }, options);
38
- const progressBar = cli_ux_1.default.progress({
39
- format: `Dumping ${collection} |{bar}| {percentage}% || {value}/{total} documents`
40
- });
41
- progressBar.start(results.total, 0);
42
- const rawDocuments = {
43
- [index]: {
44
- [collection]: []
45
- }
46
- };
47
- do {
48
- progressBar.update(results.fetched);
49
- for (const hit of results.hits) {
50
- let document = null;
51
- if (format.toLocaleLowerCase() === 'jsonl') {
52
- document = {
53
- _id: hit._id,
54
- body: hit._source
55
- };
56
- await writeLine(document);
137
+ }
138
+ onResult(document) {
139
+ return this.writeLine({ _id: document._id, body: document._source });
140
+ }
141
+ get fileExtension() {
142
+ return 'jsonl';
143
+ }
144
+ }
145
+ class KuzzleDumper extends JSONLDumper {
146
+ constructor() {
147
+ super(...arguments);
148
+ this.rawDocuments = {
149
+ [this.index]: {
150
+ [this.collection]: []
57
151
  }
58
- else {
59
- rawDocuments[index][collection].push({
60
- index: {
61
- _id: hit._id
62
- }
63
- });
64
- rawDocuments[index][collection].push(hit._source);
152
+ };
153
+ }
154
+ get fileExtension() {
155
+ return 'json';
156
+ }
157
+ async onResult(document) {
158
+ this.rawDocuments[this.index][this.collection].push({
159
+ index: {
160
+ _id: document._id
161
+ }
162
+ });
163
+ this.rawDocuments[this.index][this.collection].push(document._source);
164
+ return;
165
+ }
166
+ tearDown() {
167
+ return this.writeLine(this.rawDocuments);
168
+ }
169
+ }
170
+ class CSVDumper extends AbstractDumper {
171
+ constructor(sdk, index, collection, batchSize, destPath, query = {}, fields, separator = ',') {
172
+ super(sdk, index, collection, batchSize, destPath, query);
173
+ this.fields = fields;
174
+ this.separator = separator;
175
+ }
176
+ get fileExtension() {
177
+ return 'csv';
178
+ }
179
+ async setup() {
180
+ if (!this.fields.length) {
181
+ // If no field has been selected, then all fields are selected.
182
+ const mappings = await this.sdk.collection.getMapping(this.index, this.collection);
183
+ if (!mappings.properties) {
184
+ return;
65
185
  }
186
+ this.fields = Object.keys(flattenObject(mappings.properties));
187
+ }
188
+ else {
189
+ // Delete '_id' from the selected fields, since IDs are
190
+ // _always_ exported.
191
+ if (this.fields.includes('_id')) {
192
+ this.fields.splice(this.fields.indexOf('_id'), 1);
193
+ }
194
+ }
195
+ }
196
+ writeHeader() {
197
+ return this.writeLine(['_id', ...this.fields].join(this.separator));
198
+ }
199
+ async writeLine(line) {
200
+ if (!this.writeStream) {
201
+ throw new Error('Cannot write data: WriteStream is not initialized.');
66
202
  }
67
- } while ((results = await results.next()));
68
- if (format.toLocaleLowerCase() === 'kuzzle') {
69
- await writeLine(rawDocuments);
70
- }
71
- progressBar.stop();
72
- ndjsonStream.end();
73
- writeStream.end();
74
- return waitWrite;
203
+ this.writeStream.write(line);
204
+ this.writeStream.write('\n');
205
+ return;
206
+ }
207
+ onResult(document) {
208
+ const values = [document._id, ...(0, common_1.pickValues)(document._source, this.fields)];
209
+ return this.writeLine(values.join(this.separator));
210
+ }
211
+ }
212
+ async function dumpCollectionData(sdk, index, collection, batchSize, destPath, query = {}, format = 'jsonl', fields = []) {
213
+ let dumper;
214
+ switch (format.toLowerCase()) {
215
+ case 'jsonl':
216
+ dumper = new JSONLDumper(sdk, index, collection, batchSize, destPath, query);
217
+ return dumper.dump();
218
+ case 'csv':
219
+ dumper = new CSVDumper(sdk, index, collection, batchSize, destPath, query, fields);
220
+ return dumper.dump();
221
+ default:
222
+ dumper = new KuzzleDumper(sdk, index, collection, batchSize, destPath, query);
223
+ return dumper.dump();
224
+ }
75
225
  }
76
226
  exports.dumpCollectionData = dumpCollectionData;
77
227
  async function dumpCollectionMappings(sdk, index, collection, destPath, format = 'jsonl') {
@@ -2,9 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Editor = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const fs_1 = tslib_1.__importDefault(require("fs"));
5
+ const fs_1 = (0, tslib_1.__importDefault)(require("fs"));
6
6
  const child_process_1 = require("child_process");
7
- const tmp_1 = tslib_1.__importDefault(require("tmp"));
7
+ const tmp_1 = (0, tslib_1.__importDefault)(require("tmp"));
8
8
  class Editor {
9
9
  constructor(content = '', options = {}) {
10
10
  this._content = content;
@@ -29,7 +29,7 @@ class Editor {
29
29
  run() {
30
30
  process.env.EDITOR = process.env.EDITOR || this.defaultEditor;
31
31
  const editor = process.env.EDITOR;
32
- const response = child_process_1.spawnSync(editor, [this.tmpFile.name], { stdio: 'inherit' });
32
+ const response = (0, child_process_1.spawnSync)(editor, [this.tmpFile.name], { stdio: 'inherit' });
33
33
  if (response.status !== 0) {
34
34
  // eslint-disable-next-line
35
35
  console.error(response.stdout);
@@ -26,7 +26,7 @@ function execute(...args) {
26
26
  options = args.splice(args.length - 1)[0];
27
27
  }
28
28
  const [command, ...commandArgs] = args;
29
- const process = child_process_1.spawn(command, commandArgs, options);
29
+ const process = (0, child_process_1.spawn)(command, commandArgs, options);
30
30
  let stdout = '';
31
31
  let stderr = '';
32
32
  // eslint-disable-next-line
@@ -40,7 +40,7 @@ export declare class KuzzleSDK {
40
40
  get document(): import("kuzzle-sdk").DocumentController;
41
41
  get collection(): import("kuzzle-sdk").CollectionController;
42
42
  get index(): import("kuzzle-sdk").IndexController;
43
- get security(): any;
43
+ get security(): import("kuzzle-sdk/src/controllers/Security").SecurityController;
44
44
  get auth(): import("kuzzle-sdk").AuthController;
45
45
  get server(): any;
46
46
  get realtime(): import("kuzzle-sdk").RealtimeController;
@@ -69,6 +69,7 @@ class KuzzleSDK {
69
69
  this.sdk = new kuzzle_sdk_1.Kuzzle(new ProtocolClass(this.host, {
70
70
  port: this.port,
71
71
  sslConnection: this.ssl,
72
+ pingInterval: 5000,
72
73
  }));
73
74
  this.sdk.volatile = {
74
75
  client: `${this.appName}@${this.appVersion}`
@@ -2,14 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.restoreCollectionMappings = exports.restoreCollectionData = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
- const fs_1 = tslib_1.__importDefault(require("fs"));
7
- const ndjson = require("ndjson");
5
+ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
6
+ const fs_1 = (0, tslib_1.__importDefault)(require("fs"));
7
+ const ndjson_1 = (0, tslib_1.__importDefault)(require("ndjson"));
8
8
  function handleError(log, dumpFile, error) {
9
9
  if (error.status === 206) {
10
10
  const errorFile = `${dumpFile.split('.').slice(0, -1).join('.')}-errors.jsonl`;
11
11
  const writeStream = fs_1.default.createWriteStream(errorFile, { flags: 'a' });
12
- const serialize = ndjson.stringify().pipe(writeStream);
12
+ const serialize = ndjson_1.default.stringify().pipe(writeStream);
13
13
  serialize.on('data', (line) => (writeStream.write(line)));
14
14
  for (const partialError of error.errors) {
15
15
  serialize.write(partialError);
@@ -37,7 +37,7 @@ async function restoreCollectionData(sdk, log, batchSize, dumpFile, index, colle
37
37
  let headerSkipped = false;
38
38
  let documents = [];
39
39
  const readStream = fs_1.default.createReadStream(dumpFile)
40
- .pipe(ndjson.parse())
40
+ .pipe(ndjson_1.default.parse())
41
41
  .on('data', (obj) => {
42
42
  if (headerSkipped) {
43
43
  documents.push(obj);
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.restoreUsers = exports.restoreProfiles = exports.restoreRoles = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const lodash_1 = tslib_1.__importDefault(require("lodash"));
6
- const bluebird_1 = tslib_1.__importDefault(require("bluebird"));
5
+ const lodash_1 = (0, tslib_1.__importDefault)(require("lodash"));
6
+ const bluebird_1 = (0, tslib_1.__importDefault)(require("bluebird"));
7
7
  const sleep = (seconds) => new Promise((resolve) => setTimeout(resolve, seconds * 1000));
8
8
  async function restoreRoles(kommand, dump, preserveAnonymous = false) {
9
9
  if (dump.type !== 'roles') {