@flourish/sdk 4.2.2 → 5.1.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.
@@ -1,16 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.interpretColumn = exports.getSlicedData = exports.transposeNestedArray = exports.stripCommonFixes = exports.tidyTable = exports.dropReturnCharacters = exports.trimTrailingEmptyRows = exports.mulberry32 = exports.getRandomSeededSample = exports.getColumnTypesForData = exports.extractData = void 0;
3
+ exports.createInterpreter = void 0;
4
+ exports.extractData = extractData;
5
+ exports.getColumnTypesForData = getColumnTypesForData;
6
+ exports.getRandomSeededSample = getRandomSeededSample;
7
+ exports.mulberry32 = mulberry32;
8
+ exports.trimTrailingEmptyRows = trimTrailingEmptyRows;
9
+ exports.dropReturnCharacters = dropReturnCharacters;
10
+ exports.tidyTable = tidyTable;
11
+ exports.stripCommonFixes = stripCommonFixes;
12
+ exports.transposeNestedArray = transposeNestedArray;
13
+ exports.getSlicedData = getSlicedData;
14
+ exports.interpretColumn = interpretColumn;
15
+ exports.sortDataTables = sortDataTables;
4
16
  const interpreter_1 = require("@flourish/interpreter");
5
17
  require("./polyfills");
6
- function extractData(data_binding, data_by_id, column_types_by_id, template_data_binding) {
18
+ var interpreter_2 = require("@flourish/interpreter");
19
+ Object.defineProperty(exports, "createInterpreter", { enumerable: true, get: function () { return interpreter_2.createInterpreter; } });
20
+ function getLatestDataTimestamps(data_table_timestamps) {
21
+ const timestamps = {};
22
+ const date_values = data_table_timestamps.map(t => t.last_updated?.getTime()).filter(Boolean);
23
+ if (date_values.length) {
24
+ const latest_date = Math.max(...date_values);
25
+ timestamps.last_updated = new Date(latest_date);
26
+ }
27
+ return timestamps;
28
+ }
29
+ function extractData(data_binding, data_by_id, column_types_by_id, template_data_bindings, timestamps) {
7
30
  var columns = [];
8
31
  var data_table_ids = [];
9
32
  var num_rows = 0;
10
- var dataset = [];
33
+ var dataset = Object.assign([], { column_names: {}, metadata: {}, timestamps: {} });
11
34
  var interpreters_by_id = {};
12
- dataset.column_names = {};
13
- dataset.metadata = {};
14
35
  function getInterpretationIds(data_table_id, column_index) {
15
36
  if (!interpreters_by_id[data_table_id])
16
37
  return {};
@@ -20,9 +41,10 @@ function extractData(data_binding, data_by_id, column_types_by_id, template_data
20
41
  return by_column_index[column_index];
21
42
  }
22
43
  function getInterpreter(data_table_id, column_index) {
23
- const { type_id } = getInterpretationIds(data_table_id, column_index);
24
- if (type_id)
25
- return interpreter_1.createInterpreter.getInterpretation(type_id);
44
+ const interpretation_ids = getInterpretationIds(data_table_id, column_index);
45
+ if ("type_id" in interpretation_ids) {
46
+ return interpreter_1.createInterpreter.getInterpretation(interpretation_ids.type_id);
47
+ }
26
48
  }
27
49
  for (var data_table_id in column_types_by_id) {
28
50
  var lookup = {};
@@ -43,7 +65,7 @@ function extractData(data_binding, data_by_id, column_types_by_id, template_data
43
65
  if (data_binding[key].columns === undefined && data_binding[key].column === undefined)
44
66
  continue;
45
67
  var b = data_binding[key];
46
- b.template_data_binding = template_data_binding[key];
68
+ b.template_data_binding = template_data_bindings[key];
47
69
  b.key = key;
48
70
  if (!(b.data_table_id in data_by_id)) {
49
71
  var data_by_id_keys = [];
@@ -52,7 +74,10 @@ function extractData(data_binding, data_by_id, column_types_by_id, template_data
52
74
  console.error("Data table id " + b.data_table_id + " not in " + JSON.stringify(data_by_id_keys));
53
75
  continue;
54
76
  }
55
- var data_table = data_by_id[b.data_table_id];
77
+ const data_table = data_by_id[b.data_table_id];
78
+ if (data_table == null) {
79
+ throw new Error(`[BUG] The data from the data table with ID ${b.data_table_id} was missing`);
80
+ }
56
81
  if (data_table.length == 0) {
57
82
  console.warn("Empty data table");
58
83
  continue;
@@ -64,8 +89,9 @@ function extractData(data_binding, data_by_id, column_types_by_id, template_data
64
89
  return data_table[0][i];
65
90
  });
66
91
  dataset.metadata[key] = b.columns.map(function (i) {
67
- const { type_id, output_format_id } = getInterpretationIds(b.data_table_id, i);
68
- if (type_id) {
92
+ const interpretation_ids = getInterpretationIds(b.data_table_id, i);
93
+ if ("type_id" in interpretation_ids) {
94
+ const { type_id, output_format_id } = interpretation_ids;
69
95
  return {
70
96
  type: type_id.split("$")[0],
71
97
  type_id,
@@ -77,8 +103,9 @@ function extractData(data_binding, data_by_id, column_types_by_id, template_data
77
103
  }
78
104
  else if ("column" in b && b.column != null) {
79
105
  dataset.column_names[key] = data_table[0][b.column];
80
- const { type_id, output_format_id } = getInterpretationIds(b.data_table_id, b.column);
81
- if (type_id) {
106
+ const interpretation_ids = getInterpretationIds(b.data_table_id, b.column);
107
+ if ("type_id" in interpretation_ids) {
108
+ const { type_id, output_format_id } = interpretation_ids;
82
109
  dataset.metadata[key] = {
83
110
  type: type_id.split("$")[0],
84
111
  type_id,
@@ -95,8 +122,11 @@ function extractData(data_binding, data_by_id, column_types_by_id, template_data
95
122
  }
96
123
  columns.push(b);
97
124
  }
125
+ // gets the latest timestamp info across all data tables which are linked to by the bindings for this dataset
126
+ // (this is typically only a single data table)\
127
+ dataset.timestamps = getLatestDataTimestamps(data_table_ids.map(id => timestamps.per_data_table[id]));
98
128
  function parse(b, column_index, string_value) {
99
- if (!b.template_data_binding.data_type)
129
+ if (!b.template_data_binding?.data_type)
100
130
  return string_value;
101
131
  var interpreter = getInterpreter(b.data_table_id, column_index);
102
132
  if (interpreter && interpreter.type == "number")
@@ -112,9 +142,14 @@ function extractData(data_binding, data_by_id, column_types_by_id, template_data
112
142
  var o = {};
113
143
  for (var j = 0; j < columns.length; j++) {
114
144
  b = columns[j];
115
- var table = data_by_id[b.data_table_id];
145
+ const table = data_by_id[b.data_table_id];
146
+ if (table == null) {
147
+ throw new Error(`[BUG] The data from the data table with ID ${b.data_table_id} was missing`);
148
+ }
116
149
  if (i + 1 >= table.length)
117
150
  continue;
151
+ if (b.key == null)
152
+ throw new Error(`BUG: 'key' was ${b.key} in ${b}`);
118
153
  if ("columns" in b && b.columns != null) {
119
154
  o[b.key] = b.columns
120
155
  .filter(function (c) { return c < table[i + 1].length; })
@@ -131,7 +166,6 @@ function extractData(data_binding, data_by_id, column_types_by_id, template_data
131
166
  }
132
167
  return dataset;
133
168
  }
134
- exports.extractData = extractData;
135
169
  function getColumnTypesForData(data) {
136
170
  return transposeNestedArray(data)
137
171
  .map(function (column, i) {
@@ -146,7 +180,6 @@ function getColumnTypesForData(data) {
146
180
  return { type_id: type_id, index: i, output_format_id: type_id };
147
181
  });
148
182
  }
149
- exports.getColumnTypesForData = getColumnTypesForData;
150
183
  // Returns a random seeded sample of column values based on the column length.
151
184
  // The sample is consistent and will update if the length of column changes.
152
185
  function getRandomSeededSample(column, sample_size) {
@@ -159,7 +192,6 @@ function getRandomSeededSample(column, sample_size) {
159
192
  }
160
193
  return column;
161
194
  }
162
- exports.getRandomSeededSample = getRandomSeededSample;
163
195
  // Seeded RNG implementation taken from https://github.com/bryc/code/blob/master/jshash/PRNGs.md#mulberry32
164
196
  function mulberry32(seed) {
165
197
  let a = seed;
@@ -171,7 +203,6 @@ function mulberry32(seed) {
171
203
  return ((t ^ t >>> 14) >>> 0) / 4294967296;
172
204
  };
173
205
  }
174
- exports.mulberry32 = mulberry32;
175
206
  function trimTrailingEmptyRows(data) {
176
207
  for (var i = data.length; i-- > 1;) {
177
208
  if (!data[i] || !data[i].length || (Array.isArray(data[i]) && data[i].findIndex(function (col) { return col !== null && col !== ""; }) == -1)) {
@@ -182,7 +213,6 @@ function trimTrailingEmptyRows(data) {
182
213
  }
183
214
  return data;
184
215
  }
185
- exports.trimTrailingEmptyRows = trimTrailingEmptyRows;
186
216
  function dropReturnCharacters(data) {
187
217
  for (const row of data) {
188
218
  for (let i = 0; i < row.length; i++) {
@@ -195,7 +225,6 @@ function dropReturnCharacters(data) {
195
225
  }
196
226
  return data;
197
227
  }
198
- exports.dropReturnCharacters = dropReturnCharacters;
199
228
  /**
200
229
  * Takes an array of arrays (typically tabular data) and rewrites
201
230
  * it so that:
@@ -223,21 +252,24 @@ function tidyTable(data) {
223
252
  if (typeof value !== "string") {
224
253
  value = "" + value;
225
254
  }
255
+ if (typeof value !== "string") {
256
+ throw new Error("BUG: somehow value was not a string");
257
+ }
226
258
  // Now value is a definitely a string, strip any leading
227
259
  // or trailing whitespace.
228
260
  row[i] = value.trim();
229
261
  }
230
262
  }
263
+ // TypeScript can't infer that the returned data is definitely all
264
+ // strings so use a cast.
231
265
  return data;
232
266
  }
233
- exports.tidyTable = tidyTable;
234
267
  var ERROR_STRINGS = ["#DIV/0", "#N/A", "#NAME?", "#NULL!", "#NUM!", "#REF!", "#VALUE!", "#ERROR!"];
235
268
  var interpreter = (0, interpreter_1.createInterpreter)().nMax(Infinity).nFailingValues(8).failureFraction(0.1);
236
269
  function stripCommonFixes(str) {
237
270
  str = str || "";
238
271
  return str.replace(/[€£$¥%º]/g, "");
239
272
  }
240
- exports.stripCommonFixes = stripCommonFixes;
241
273
  function transposeNestedArray(nested_array) {
242
274
  var n_inner = nested_array.length;
243
275
  var n_outer = n_inner > 0 ? nested_array[0].length : 0;
@@ -251,7 +283,6 @@ function transposeNestedArray(nested_array) {
251
283
  }
252
284
  return transposed_array;
253
285
  }
254
- exports.transposeNestedArray = transposeNestedArray;
255
286
  function getSlicedData(arr) {
256
287
  const n = arr.length;
257
288
  if (n > 100)
@@ -268,7 +299,6 @@ function getSlicedData(arr) {
268
299
  return arr.slice(1, n);
269
300
  return arr.slice(0, 1);
270
301
  }
271
- exports.getSlicedData = getSlicedData;
272
302
  function interpretColumn(arr) {
273
303
  var idata = arr.filter(function (d) {
274
304
  return d && !ERROR_STRINGS.includes(d.trim());
@@ -276,4 +306,31 @@ function interpretColumn(arr) {
276
306
  .map(stripCommonFixes);
277
307
  return interpreter(idata);
278
308
  }
279
- exports.interpretColumn = interpretColumn;
309
+ function sortDataTables(data_tables, data_bindings) {
310
+ // Sort data tables to match order in the template data bindings
311
+ if (!data_bindings || !data_bindings.length)
312
+ return;
313
+ if (!data_tables || !data_tables.length)
314
+ return;
315
+ var table_names = [];
316
+ data_bindings.forEach(function (data_binding) {
317
+ if (typeof data_binding === "string")
318
+ return;
319
+ let column;
320
+ if ("column" in data_binding) {
321
+ column = data_binding.column;
322
+ }
323
+ else if ("columns" in data_binding) {
324
+ column = data_binding.columns;
325
+ }
326
+ if (column) {
327
+ var table_name = column.match(/^(?:[^:]|:[^:])*/);
328
+ if (table_name && table_names.indexOf(table_name[0]) == -1)
329
+ table_names.push(table_name[0]);
330
+ }
331
+ });
332
+ return data_tables.sort(function (dt1, dt2) {
333
+ var i = table_names.indexOf(dt1.name), j = table_names.indexOf(dt2.name);
334
+ return (i == -1 ? Infinity : i) < (j == -1 ? Infinity : j) ? -1 : 1;
335
+ });
336
+ }
@@ -1,3 +1,6 @@
1
- export function safeStringify(obj: any): string | undefined;
2
- export function javaScriptStringify(v: any): any;
3
- export function stringifyPreparedData(data: any): string;
1
+ import { DatasetType } from "./types";
2
+ export declare function safeStringify(obj: unknown): string | undefined;
3
+ export declare function javaScriptStringify(v: unknown): string | undefined;
4
+ export declare function stringifyPreparedData(data: {
5
+ [dataset: string]: DatasetType;
6
+ }): string;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.stringifyPreparedData = exports.javaScriptStringify = exports.safeStringify = void 0;
3
+ exports.safeStringify = safeStringify;
4
+ exports.javaScriptStringify = javaScriptStringify;
5
+ exports.stringifyPreparedData = stringifyPreparedData;
4
6
  function escapeChar(c) {
5
7
  var hex = c.charCodeAt(0).toString(16);
6
8
  while (hex.length < 4)
@@ -15,7 +17,6 @@ function safeStringify(obj) {
15
17
  return undefined;
16
18
  return raw.replace(/[\u2028\u2029<]/g, escapeChar);
17
19
  }
18
- exports.safeStringify = safeStringify;
19
20
  function javaScriptStringify(v) {
20
21
  var type = typeof v;
21
22
  if (v == null) {
@@ -40,9 +41,8 @@ function javaScriptStringify(v) {
40
41
  throw new Error("javaScriptStringify couldn't handle " + type + " object: " + v);
41
42
  }
42
43
  }
43
- exports.javaScriptStringify = javaScriptStringify;
44
44
  function stringifyDataset(dataset) {
45
- return "(function(array, column_names, metadata){ array.column_names = column_names; array.metadata = metadata; return array; })(" + javaScriptStringify(dataset) + ", " + safeStringify(dataset.column_names) + ", " + safeStringify(dataset.metadata) + ")";
45
+ return "(function(array, column_names, metadata, timestamps){ array.column_names = column_names; array.metadata = metadata; array.timestamps = timestamps; return array; })(" + javaScriptStringify(dataset) + ", " + safeStringify(dataset.column_names) + ", " + safeStringify(dataset.metadata) + ", " + javaScriptStringify(dataset.timestamps) + ")";
46
46
  }
47
47
  function stringifyPreparedData(data) {
48
48
  var s = "{";
@@ -57,4 +57,3 @@ function stringifyPreparedData(data) {
57
57
  s += "}";
58
58
  return s;
59
59
  }
60
- exports.stringifyPreparedData = stringifyPreparedData;
@@ -1,11 +1,16 @@
1
1
  "use strict";
2
2
  /* This file is used by the story player, and must be IE-compatible */
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.getStateChanges = exports.deepEqual = exports.deepCopyObject = exports.merge = exports.unflatten = exports.flatten = exports.isObject = void 0;
4
+ exports.isObject = isObject;
5
+ exports.flatten = flatten;
6
+ exports.unflatten = unflatten;
7
+ exports.merge = merge;
8
+ exports.deepCopyObject = deepCopyObject;
9
+ exports.deepEqual = deepEqual;
10
+ exports.getStateChanges = getStateChanges;
5
11
  function isObject(x) {
6
12
  return !Array.isArray(x) && typeof x === "object" && x != null;
7
13
  }
8
- exports.isObject = isObject;
9
14
  /* Example: { a: { b: { c: 2, d: 3 } } } ↦
10
15
  {
11
16
  "a": { b: { c: 2, d: 3 } },
@@ -29,7 +34,6 @@ function flatten(o, keys, result) {
29
34
  }
30
35
  return result;
31
36
  }
32
- exports.flatten = flatten;
33
37
  // { "a.b.c": 2, "a.b.d":3 } → { a: { b: { c: 2, d: 3 } } }
34
38
  function unflatten(o) {
35
39
  var r = {};
@@ -45,7 +49,6 @@ function unflatten(o) {
45
49
  }
46
50
  return r;
47
51
  }
48
- exports.unflatten = unflatten;
49
52
  function merge(dest, source) {
50
53
  for (var prop in source) {
51
54
  if (isObject(dest[prop]) && isObject(source[prop])) {
@@ -57,7 +60,6 @@ function merge(dest, source) {
57
60
  }
58
61
  return dest;
59
62
  }
60
- exports.merge = merge;
61
63
  function deepCopyObject(obj) {
62
64
  if (obj == null)
63
65
  return obj;
@@ -75,7 +77,6 @@ function deepCopyObject(obj) {
75
77
  }
76
78
  return copy;
77
79
  }
78
- exports.deepCopyObject = deepCopyObject;
79
80
  // Simple deep equality test for JSON-definable objects
80
81
  // The idea is that two objects test equal if they would
81
82
  // JSON.stringify to the same thing, modulo key ordering.
@@ -126,7 +127,6 @@ function deepEqual(a, b) {
126
127
  return typeof b === "undefined";
127
128
  }
128
129
  }
129
- exports.deepEqual = deepEqual;
130
130
  function getStateChanges(state1, state2) {
131
131
  var diff = {};
132
132
  for (var name in state2) {
@@ -141,4 +141,3 @@ function getStateChanges(state1, state2) {
141
141
  }
142
142
  return diff;
143
143
  }
144
- exports.getStateChanges = getStateChanges;
@@ -0,0 +1,63 @@
1
+ type ColumnTypeInMetadata = {
2
+ type: string;
3
+ type_id: string;
4
+ output_format_id: string;
5
+ };
6
+ export type DatasetType = Record<string, unknown>[] & {
7
+ column_names: {
8
+ [data_binding_key: string]: string | string[];
9
+ };
10
+ metadata: {
11
+ [data_binding_key: string]: ColumnTypeInMetadata | (ColumnTypeInMetadata | null)[];
12
+ };
13
+ timestamps: {
14
+ last_updated?: Date;
15
+ };
16
+ };
17
+ export type DataBinding = {
18
+ data_table_id: number;
19
+ } & ({
20
+ column: number;
21
+ columns?: null;
22
+ } | {
23
+ column?: null;
24
+ columns: number[];
25
+ });
26
+ export type DataBindings = Record<string, DataBinding>;
27
+ export type TemplateDataBinding = {
28
+ dataset: string;
29
+ key: string;
30
+ name?: string;
31
+ type?: string;
32
+ description?: string;
33
+ data_type?: string[];
34
+ assignment?: {
35
+ can_rebind?: boolean;
36
+ min_columns?: number;
37
+ max_columns?: number;
38
+ hints: Record<string, unknown>;
39
+ };
40
+ optional?: boolean;
41
+ } & ({
42
+ column: string;
43
+ } | {
44
+ columns: string;
45
+ });
46
+ export type KeyToTemplateDataBinding = {
47
+ [key: string]: TemplateDataBinding;
48
+ };
49
+ export type DatasetToKeyToTemplateDataBinding = {
50
+ [dataset: string]: KeyToTemplateDataBinding;
51
+ };
52
+ export type ColumnType = {
53
+ index: number;
54
+ type_id: string;
55
+ output_format_id: string;
56
+ };
57
+ export type ColumnTypesById = {
58
+ [data_table_id: string]: ColumnType[];
59
+ };
60
+ export type NullableColumnTypesById = {
61
+ [data_table_id: string]: ColumnType[] | null;
62
+ };
63
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ // Data binding types:
3
+ Object.defineProperty(exports, "__esModule", { value: true });
package/lib/cmd/login.js CHANGED
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
2
 
3
+ var { read } = require("read");
3
4
  var readline = require("readline"),
4
-
5
- read = require("read"),
6
-
7
5
  log = require("../log"),
8
6
  sdk = require("../sdk");
9
7
 
@@ -26,25 +24,22 @@ exports.command = function login(args) {
26
24
  }
27
25
 
28
26
  function getPassword() {
29
- return new Promise(function(resolve, reject) {
30
- read({ prompt: "Password: ", silent: true }, function(error, password) {
31
- if (error) return reject(error);
32
- resolve(password);
27
+ return read({ prompt: "Password: ", silent: true })
28
+ .then((response) => {
29
+ console.log();
30
+ return response;
33
31
  });
34
- });
35
32
  }
36
33
 
37
34
  function getToken() {
38
- return new Promise(function(resolve, reject) {
39
- if (args.token) {
40
- resolve(args.token);
41
- return;
42
- }
43
- read({ prompt: "SDK Token: ", silent: true }, function(error, token) {
44
- if (error) return reject(error);
45
- resolve(token);
35
+ if (args.token) {
36
+ return Promise.resolve(args.token);
37
+ }
38
+ return read({ prompt: "SDK Token: ", silent: true })
39
+ .then((response) => {
40
+ console.log();
41
+ return response;
46
42
  });
47
- });
48
43
  }
49
44
 
50
45
  function login(email, password) {
package/lib/cmd/logout.js CHANGED
@@ -3,15 +3,27 @@
3
3
  var log = require("../log"),
4
4
  sdk = require("../sdk");
5
5
 
6
- exports.command = function logout() {
7
- sdk.deleteSdkTokens()
8
- .then(() => log.victory("Deleted all SDK tokens"))
9
- .catch((error) => log.die(error));
6
+ exports.command = async function logout(server_opts) {
7
+ try {
8
+ await sdk.request(server_opts, "user/logout", {}, { exit_on_failure: false });
9
+ }
10
+ catch (e) {
11
+ log.warn("Failed to revoke SDK Token. Your token may not correspond to a valid active user session.");
12
+ }
13
+
14
+ // Delete token from local file
15
+ try {
16
+ await sdk.deleteSdkToken(server_opts.host);
17
+ log.victory("Deleted SDK token.");
18
+ }
19
+ catch (e) {
20
+ log.die(e);
21
+ }
10
22
  };
11
23
 
12
24
  exports.help = `
13
25
  flourish logout
14
26
 
15
- Deletes the .flourish_sdk file from your HOME or USERPROFILE directory. You
27
+ Revokes the active user token and deletes it from the .flourish_sdk file from your HOME or USERPROFILE directory. You
16
28
  will not be able to communicate with the server until you “flourish login”
17
29
  `;
@@ -5,7 +5,6 @@ var fs = require("fs"),
5
5
 
6
6
  archiver = require("archiver"),
7
7
  tmp = require("tmp"),
8
- FormData = require("form-data"),
9
8
 
10
9
  d3_dsv = require("d3-dsv"),
11
10
 
@@ -97,16 +96,12 @@ function zipUpTemplate(template_dir, config) {
97
96
  }
98
97
 
99
98
  async function uploadTemplate(server_opts, template_id, external_version, zip_filename) {
99
+ const { FormData, fileFrom } = await import("node-fetch");
100
100
  const body = new FormData();
101
- const stat = await fs.promises.stat(zip_filename);
102
101
 
103
102
  body.append("id", template_id);
104
103
  body.append("version", external_version);
105
- body.append("template", fs.createReadStream(zip_filename), {
106
- contentType: "application/zip",
107
- filename: "template.zip",
108
- knownLength: stat.size
109
- });
104
+ body.append("template", await fileFrom(zip_filename, "application/zip"), "template.zip");
110
105
 
111
106
  return sdk.request(server_opts, "template/publish", body);
112
107
  }
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
2
 
3
+ var { read } = require("read");
3
4
  var readline = require("readline"),
4
-
5
- read = require("read"),
6
-
7
5
  log = require("../log"),
8
6
  sdk = require("../sdk");
9
7
 
@@ -17,22 +15,21 @@ exports.command = function register(args) {
17
15
 
18
16
  function getPassword() {
19
17
  return new Promise(function(resolve, reject) {
20
- read({ prompt: "Password: ", silent: true }, function(error, pw_i) {
21
- if (error) return reject(error);
22
-
23
- read({ prompt: "Confirm password: ", silent: true }, function(error, pw_ii) {
24
- if (error) return reject(error);
18
+ read({ prompt: "Password: ", silent: true }).then((pw_i) => {
19
+ read({ prompt: "Confirm password: ", silent: true }).then((pw_ii) => {
25
20
  if (pw_i === pw_ii) return resolve(pw_i);
26
21
 
27
22
  log.warn("Passwords not the same! Try again.");
28
- read({ prompt: "Confirm password: ", silent: true }, function(error, pw_iii) {
29
- if (error) return reject(error);
30
23
 
24
+ read({ prompt: "Confirm password: ", silent: true }).then((pw_iii) => {
31
25
  if (pw_i === pw_iii) return resolve(pw_i);
32
26
  reject(new Error("Passwords still don’t match. Exiting."));
33
- });
34
- });
35
- });
27
+ })
28
+ .catch(reject);
29
+ })
30
+ .catch(reject);
31
+ })
32
+ .catch(reject);
36
33
  });
37
34
  }
38
35