kourou 0.25.1 → 0.25.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.
package/README.md CHANGED
@@ -26,7 +26,7 @@ $ npm install -g kourou
26
26
  $ kourou COMMAND
27
27
  running command...
28
28
  $ kourou (-v|--version|version)
29
- kourou/0.25.1 linux-x64 node-v16.15.0
29
+ kourou/0.25.2 linux-x64 node-v14.20.0
30
30
  $ kourou --help [COMMAND]
31
31
  USAGE
32
32
  $ kourou COMMAND
@@ -506,6 +506,9 @@ OPTIONS
506
506
  --ssl
507
507
  Use SSL to connect to Kuzzle
508
508
 
509
+ --type=type
510
+ [default: all] Type of the export: all, mappings, data
511
+
509
512
  --username=username
510
513
  [default: anonymous] Kuzzle username (local strategy)
511
514
 
@@ -938,6 +941,8 @@ OPTIONS
938
941
 
939
942
  --ssl Use SSL to connect to Kuzzle
940
943
 
944
+ --type=type [default: all] Type of the export: all, mappings, data
945
+
941
946
  --username=username [default: anonymous] Kuzzle username (local strategy)
942
947
 
943
948
  EXAMPLES
@@ -20,6 +20,7 @@ export default class CollectionExport extends Kommand {
20
20
  format: flags.IOptionFlag<string>;
21
21
  fields: flags.IOptionFlag<string | undefined>;
22
22
  scrollTTL: flags.IOptionFlag<string>;
23
+ type: flags.IOptionFlag<string>;
23
24
  };
24
25
  static args: {
25
26
  name: string;
@@ -22,10 +22,16 @@ class CollectionExport extends common_1.Kommand {
22
22
  }
23
23
  const countAll = await this.sdk.document.count(this.args.index, this.args.collection);
24
24
  const count = await this.sdk.document.count(this.args.index, this.args.collection, { query });
25
- this.logInfo(`Dumping ${count} of ${countAll} documents from collection "${this.args.index}:${this.args.collection}" in ${exportPath} ...`);
25
+ this.logInfo(`Dumping collection "${this.args.index}:${this.args.collection}" in ${exportPath} ...`);
26
26
  fs_1.default.mkdirSync(exportPath, { recursive: true });
27
- await (0, dump_collection_1.dumpCollectionMappings)(this.sdk, this.args.index, this.args.collection, exportPath, this.flags.format);
28
- await (0, dump_collection_1.dumpCollectionData)(this.sdk, this.args.index, this.args.collection, Number(this.flags["batch-size"]), exportPath, query, this.flags.format, fields, this.flags.scrollTTL);
27
+ if (this.flags.type === "all" || this.flags.type === "mappings") {
28
+ this.logInfo(`Dumping collection mappings ...`);
29
+ await (0, dump_collection_1.dumpCollectionMappings)(this.sdk, this.args.index, this.args.collection, exportPath, this.flags.format);
30
+ }
31
+ if (this.flags.type === "all" || this.flags.type === "data") {
32
+ this.logInfo(`Dumping collection ${count} of ${countAll} documents ...`);
33
+ await (0, dump_collection_1.dumpCollectionData)(this.sdk, this.args.index, this.args.collection, Number(this.flags["batch-size"]), exportPath, query, this.flags.format, fields, this.flags.scrollTTL);
34
+ }
29
35
  this.logOk(`Collection ${this.args.index}:${this.args.collection} dumped`);
30
36
  }
31
37
  }
@@ -60,6 +66,9 @@ exportable fields in the mapping will be exported.`,
60
66
  description: `The scroll TTL option to pass to the dump operation (which performs a document.search under the hood),
61
67
  expressed in ms format, e.g. '2s', '1m', '3h'.`,
62
68
  default: "20s",
69
+ }), type: command_1.flags.string({
70
+ description: "Type of the export: all, mappings, data",
71
+ default: "all",
63
72
  }) }, kuzzle_1.kuzzleFlags), { protocol: command_1.flags.string({
64
73
  description: "Kuzzle protocol (http or websocket)",
65
74
  default: "ws",
@@ -5,6 +5,7 @@ export default class IndexExport extends Kommand {
5
5
  static description: string;
6
6
  static flags: {
7
7
  protocol: flags.IOptionFlag<string>;
8
+ type: flags.IOptionFlag<string>;
8
9
  host: flags.IOptionFlag<string>;
9
10
  port: flags.IOptionFlag<string>;
10
11
  ssl: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
@@ -19,11 +19,18 @@ class IndexExport extends common_1.Kommand {
19
19
  const { collections } = await this.sdk.collection.list(this.args.index);
20
20
  for (const collection of collections) {
21
21
  try {
22
- if (collection.type !== "realtime") {
22
+ if (collection.type === "realtime") {
23
+ continue;
24
+ }
25
+ if (this.flags.type === "all" || this.flags.type === "mappings") {
26
+ this.logInfo(`Dumping collection "${collection.name}" mappings ...`);
23
27
  await (0, dump_collection_1.dumpCollectionMappings)(this.sdk, this.args.index, collection.name, exportPath, this.flags.format);
28
+ }
29
+ if (this.flags.type === "all" || this.flags.type === "data") {
30
+ this.logInfo(`Dumping collection "${collection.name}" documents ...`);
24
31
  await (0, dump_collection_1.dumpCollectionData)(this.sdk, this.args.index, collection.name, Number(this.flags["batch-size"]), exportPath, query, this.flags.format, this.flags.scrollTTL);
25
- cli_ux_1.default.action.stop();
26
32
  }
33
+ cli_ux_1.default.action.stop();
27
34
  }
28
35
  catch (error) {
29
36
  this.logKo(`Error when exporting collection "${collection.name}": ${error}`);
@@ -53,6 +60,9 @@ expressed in ms format, e.g. '2s', '1m', '3h'.`,
53
60
  }) }, kuzzle_1.kuzzleFlags), { protocol: command_1.flags.string({
54
61
  description: "Kuzzle protocol (http or websocket)",
55
62
  default: "ws",
63
+ }), type: command_1.flags.string({
64
+ description: "Type of the export: all, mappings, data",
65
+ default: "all",
56
66
  }) });
57
67
  IndexExport.args = [{ name: "index", description: "Index name", required: true }];
58
68
  IndexExport.examples = [
@@ -15,7 +15,15 @@ class PaasLogs extends PaasKommand_1.PaasKommand {
15
15
  /**
16
16
  * Allowed colors for pod names.
17
17
  */
18
- this.allColors = [chalk_1.default.red, chalk_1.default.green, chalk_1.default.yellow, chalk_1.default.blue, chalk_1.default.magenta, chalk_1.default.cyan, chalk_1.default.gray];
18
+ this.allColors = [
19
+ chalk_1.default.red,
20
+ chalk_1.default.green,
21
+ chalk_1.default.yellow,
22
+ chalk_1.default.blue,
23
+ chalk_1.default.magenta,
24
+ chalk_1.default.cyan,
25
+ chalk_1.default.gray,
26
+ ];
19
27
  /**
20
28
  * Available colors for pod names.
21
29
  */
@@ -34,8 +42,12 @@ class PaasLogs extends PaasKommand_1.PaasKommand {
34
42
  this.logInfo(`Logged as "${user._id}" for project "${this.flags.project || this.getProject()}"`);
35
43
  const separator = "\t";
36
44
  // Parse the time arguments
37
- const since = this.flags.since ? chrono.parseDate(this.flags.since).toISOString() : undefined;
38
- const until = this.flags.until ? chrono.parseDate(this.flags.until).toISOString() : undefined;
45
+ const since = this.flags.since
46
+ ? chrono.parseDate(this.flags.since).toISOString()
47
+ : undefined;
48
+ const until = this.flags.until
49
+ ? chrono.parseDate(this.flags.until).toISOString()
50
+ : undefined;
39
51
  // Perform the streamed request
40
52
  const incomingMessage = await this.paas.queryHttpStream({
41
53
  controller: "application",
@@ -63,18 +75,19 @@ class PaasLogs extends PaasKommand_1.PaasKommand {
63
75
  const data = JSON.parse(line);
64
76
  // Exclude logs that are empty or that are not from a pod
65
77
  if (!data.content || !data.podName) {
66
- this.logKo(line);
67
78
  continue;
68
79
  }
69
80
  // Get the pod color
70
81
  const podColor = this.getPodColor(data.podName);
71
82
  // Display the log
72
- const timestamp = this.flags.timestamp ? `[${new Date(data.timeStamp).toLocaleString()}] ` : "";
83
+ const timestamp = this.flags.timestamp
84
+ ? `[${new Date(data.timeStamp).toLocaleString()}] `
85
+ : "";
73
86
  const name = podColor(`${data.podName}${separator}`);
74
87
  this.log(`${timestamp}${name}| ${data.content}`);
75
88
  }
76
89
  catch (error) {
77
- this.logKo(`Unable to parse the following line: ${line}`);
90
+ this.logKo(`Error while parsing log: ${error} (Received: "${line}")`);
78
91
  }
79
92
  }
80
93
  }
@@ -106,13 +119,15 @@ class PaasLogs extends PaasKommand_1.PaasKommand {
106
119
  }
107
120
  getNumberOfSpaces(names, currentName) {
108
121
  const end = 10;
109
- let max = { name: '', length: 0 };
122
+ let max = { name: "", length: 0 };
110
123
  for (const name of names) {
111
124
  if (max.length < name.length) {
112
125
  max = { name: name, length: name.length };
113
126
  }
114
127
  }
115
- return currentName === max.name ? end : end + (max.length - currentName.length);
128
+ return currentName === max.name
129
+ ? end
130
+ : end + (max.length - currentName.length);
116
131
  }
117
132
  /**
118
133
  * Returns the color to use for a pod name.
@@ -81,6 +81,7 @@ class AbstractDumper {
81
81
  * @returns a promise resolving when the dump is finished.
82
82
  */
83
83
  async dump() {
84
+ fs_1.default.mkdirSync(this.collectionDir, { recursive: true });
84
85
  this.filename = path_1.default.join(this.collectionDir, `documents.${this.fileExtension}`);
85
86
  this.writeStream = fs_1.default.createWriteStream(this.filename);
86
87
  const waitWrite = new Promise((resolve, reject) => this.writeStream ? this.writeStream.on("finish", resolve) : reject());
@@ -164,7 +164,7 @@ class KuzzleSDK {
164
164
  const options = {
165
165
  method: "POST",
166
166
  headers: {
167
- "Authorization": `Bearer ${this.sdk.jwt}`,
167
+ Authorization: `Bearer ${this.sdk.jwt}`,
168
168
  "Content-Length": Buffer.byteLength(body),
169
169
  "Content-Type": "application/json",
170
170
  },
@@ -6,18 +6,16 @@ const fs_1 = (0, tslib_1.__importDefault)(require("fs"));
6
6
  const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
7
7
  const ndjson_1 = (0, tslib_1.__importDefault)(require("ndjson"));
8
8
  function handleError(log, dumpFile, error) {
9
- if (error.status === 206) {
9
+ if (error.errors) {
10
10
  const errorFile = `${dumpFile
11
11
  .split(".")
12
12
  .slice(0, -1)
13
13
  .join(".")}-errors.jsonl`;
14
14
  const writeStream = fs_1.default.createWriteStream(errorFile, { flags: "a" });
15
- const serialize = ndjson_1.default.stringify().pipe(writeStream);
16
- serialize.on("data", (line) => writeStream.write(line));
17
15
  for (const partialError of error.errors) {
18
- serialize.write(partialError);
16
+ writeStream.write(JSON.stringify(partialError) + '\n');
19
17
  }
20
- serialize.end();
18
+ writeStream.end();
21
19
  log(chalk_1.default.red(`[X] Error importing ${dumpFile}. See errors in ${errorFile}`));
22
20
  }
23
21
  else {
@@ -31,6 +29,7 @@ async function restoreCollectionData(sdk, log, batchSize, dumpFile, index, colle
31
29
  action: "mWrite",
32
30
  index: "",
33
31
  collection: "",
32
+ strict: true,
34
33
  body: {
35
34
  documents: [{}],
36
35
  },
@@ -90,8 +89,8 @@ async function restoreCollectionData(sdk, log, batchSize, dumpFile, index, colle
90
89
  mWriteRequest.body.documents = documents;
91
90
  sdk
92
91
  .query(mWriteRequest)
93
- .then(() => {
94
- total += mWriteRequest.body.documents.length;
92
+ .then((response) => {
93
+ total += response.result.successes.length;
95
94
  process.stdout.write(` ${total} documents imported`);
96
95
  process.stdout.write("\r");
97
96
  resolve(undefined);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kourou",
3
3
  "description": "The CLI that helps you manage your Kuzzle instances",
4
- "version": "0.25.1",
4
+ "version": "0.25.2",
5
5
  "author": "The Kuzzle Team <support@kuzzle.io>",
6
6
  "bin": {
7
7
  "kourou": "./bin/run"