@flourish/sdk 5.0.0 → 5.2.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 (103) hide show
  1. package/RELEASE_NOTES.md +8 -0
  2. package/bin/flourish.js +6 -6
  3. package/common/embed/credit.js +5 -5
  4. package/common/embed/customer_analytics.js +20 -17
  5. package/common/embed/embedding.js +71 -38
  6. package/common/embed/localizations.d.ts +8 -8
  7. package/common/embed/localizations.js +4 -4
  8. package/common/embed/parse_query_params.js +2 -1
  9. package/common/package.json +11 -1
  10. package/common/tsconfig.sdk.tsbuildinfo +1 -1
  11. package/common/utils/columns.js +34 -22
  12. package/common/utils/data.d.ts +36 -15
  13. package/common/utils/data.js +136 -51
  14. package/common/utils/json.d.ts +6 -3
  15. package/common/utils/json.js +12 -9
  16. package/common/utils/polyfills.js +1 -1
  17. package/common/utils/state.d.ts +2 -2
  18. package/common/utils/state.js +43 -27
  19. package/common/utils/types.d.ts +63 -0
  20. package/common/utils/types.js +3 -0
  21. package/lib/cmd/assign-version-number.js +5 -5
  22. package/lib/cmd/build.js +1 -1
  23. package/lib/cmd/delete.js +2 -2
  24. package/lib/cmd/history.js +4 -2
  25. package/lib/cmd/list.js +13 -11
  26. package/lib/cmd/login.js +1 -1
  27. package/lib/cmd/logout.js +17 -5
  28. package/lib/cmd/publish.js +13 -13
  29. package/lib/cmd/register.js +3 -3
  30. package/lib/cmd/run.js +3 -3
  31. package/lib/cmd/upgrade/1-convert-config-to-yaml.js +14 -14
  32. package/lib/cmd/upgrade/2-convert-index-html.js +4 -4
  33. package/lib/cmd/upgrade/3-add-build-config.js +5 -5
  34. package/lib/cmd/upgrade/4-remove-autoheight-config.js +3 -3
  35. package/lib/cmd/upgrade/index.js +6 -6
  36. package/lib/common.js +11 -7
  37. package/lib/log.js +7 -7
  38. package/lib/sdk.js +86 -38
  39. package/lib/validate_config.js +30 -30
  40. package/package.json +5 -3
  41. package/rollup.config.mjs +20 -0
  42. package/server/columns.js +201 -0
  43. package/server/comms_js.js +3 -3
  44. package/server/data.js +327 -0
  45. package/server/index.js +62 -44
  46. package/server/index_html.js +16 -9
  47. package/server/json.js +66 -0
  48. package/server/views/index.html +3 -3
  49. package/site/embedded.js +1 -1
  50. package/site/favicon.ico +0 -0
  51. package/site/fonts/canva-sans/WOFF/CanvaSans-Bold.woff +0 -0
  52. package/site/fonts/canva-sans/WOFF/CanvaSans-Bold.woff2 +0 -0
  53. package/site/fonts/canva-sans/WOFF/CanvaSans-Regular.woff +0 -0
  54. package/site/fonts/canva-sans/WOFF/CanvaSans-Regular.woff2 +0 -0
  55. package/site/fonts/canva-sans/WOFF/CanvaSansDisplay-Bold.woff +0 -0
  56. package/site/fonts/canva-sans/WOFF/CanvaSansDisplay-Bold.woff2 +0 -0
  57. package/site/fonts/canva-sans/WOFF/CanvaSansDisplay-Regular.woff +0 -0
  58. package/site/fonts/canva-sans/WOFF/CanvaSansDisplay-Regular.woff2 +0 -0
  59. package/site/fonts/canva-sans-variable/TTF/CanvaSans-VF.ttf +0 -0
  60. package/site/fonts/canva-sans-variable/TTF/CanvaSansDisplay-VF.ttf +0 -0
  61. package/site/fonts/canva-sans-variable/WOFF/CanvaSans-VF.woff +0 -0
  62. package/site/fonts/canva-sans-variable/WOFF/CanvaSansDisplay-VF.woff +0 -0
  63. package/site/fonts/canva-sans.css +53 -0
  64. package/site/images/bosh-white.svg +12 -0
  65. package/site/images/bosh.svg +10 -6
  66. package/site/images/flourish_logo.svg +20 -0
  67. package/site/images/flourish_logo_white.svg +20 -0
  68. package/site/images/icon-chart-bar.svg +3 -0
  69. package/site/images/icon-chart-line.svg +3 -0
  70. package/site/images/icon-chart-pie.svg +3 -0
  71. package/site/images/icon-chevron-down-small-white.svg +3 -0
  72. package/site/images/icon-editable.svg +1 -8
  73. package/site/images/icon-gift.svg +3 -0
  74. package/site/images/icon-grid-view-white.svg +3 -0
  75. package/site/images/icon-grid-view.svg +3 -0
  76. package/site/images/icon-presentation.svg +2 -2
  77. package/site/images/icon-presenter.svg +3 -0
  78. package/site/images/icon-private.svg +1 -1
  79. package/site/images/icon-star.svg +3 -0
  80. package/site/images/icon-table-border-all.svg +3 -0
  81. package/site/images/icon-table-white.svg +3 -0
  82. package/site/images/icon-table.svg +3 -0
  83. package/site/images/icon-upload-black.svg +3 -0
  84. package/site/images/icon-upload-cloud.svg +3 -0
  85. package/site/images/icon-upload.svg +2 -2
  86. package/site/images/icon-viewable.svg +1 -1
  87. package/site/images/instagram-logo.svg +1 -0
  88. package/site/images/linkedin-logo.svg +1 -0
  89. package/site/images/logo.png +0 -0
  90. package/site/images/logo.svg +20 -1
  91. package/site/images/made_with_flourish.svg +38 -4
  92. package/site/images/share_image.jpg +0 -0
  93. package/site/images/slide_visualisation.png +0 -0
  94. package/site/images/spinner_data.json +1 -0
  95. package/site/images/x-logo.svg +1 -0
  96. package/site/images/youtube-logo.svg +1 -0
  97. package/site/script.js +3 -3
  98. package/site/sdk.css +2 -2
  99. package/site/talk_to_server.js +6 -4
  100. package/test/lib/sdk.js +13 -13
  101. package/test/lib/validate_config.js +61 -61
  102. package/tsconfig.json +1 -1
  103. package/site/images/logo_white.png +0 -0
@@ -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 });
@@ -9,14 +9,14 @@ exports.command = function assign_version_number(args) {
9
9
  let template_id_promise, template_version;
10
10
  if (args._.length == 2) {
11
11
  // Assume the supplied argument is a version number, and try to get the id from the current directory
12
- template_id_promise = sdk.readAndValidateConfig(".").then(({config}) => config.id);
12
+ template_id_promise = sdk.readAndValidateConfig(".").then(({ config }) => config.id);
13
13
  template_version = args._[1];
14
14
  }
15
15
  else if (args._.length == 3) {
16
16
  template_id_promise = Promise.resolve(args._[1]);
17
17
  template_version = args._[2];
18
18
  }
19
- else log.die("Usage: flourish assign-version-number [template-id] version");
19
+ else { log.die("Usage: flourish assign-version-number [template-id] version"); }
20
20
 
21
21
  try {
22
22
  semver.parse(template_version);
@@ -26,15 +26,15 @@ exports.command = function assign_version_number(args) {
26
26
  }
27
27
 
28
28
  template_id_promise.then(template_id => {
29
- if (args.as) template_id = args.as + "/" + template_id;
29
+ if (args.as) { template_id = args.as + "/" + template_id; }
30
30
  return sdk.request(args, "template/assign-version-number", { id: template_id, version: template_version })
31
31
  .then(() => {
32
32
  log.success(`Assigned version number ${template_version} to template ${template_id}`);
33
33
  });
34
34
  })
35
35
  .catch((error) => {
36
- if (args.debug) log.die("Failed to assign version number", error.message, error.stack);
37
- else log.die("Failed to assign version number", error.message);
36
+ if (args.debug) { log.die("Failed to assign version number", error.message, error.stack); }
37
+ else { log.die("Failed to assign version number", error.message); }
38
38
  });
39
39
  };
40
40
 
package/lib/cmd/build.js CHANGED
@@ -22,7 +22,7 @@ exports.command = function build(args) {
22
22
  sdk.buildRules(template_dir)
23
23
  .then(async rules => {
24
24
  const script_by_key = new Map();
25
- for (const rule of rules) script_by_key.set(rule.key, rule.script);
25
+ for (const rule of rules) { script_by_key.set(rule.key, rule.script); }
26
26
 
27
27
  const scripts_to_run = [];
28
28
  for (const key of keys) {
package/lib/cmd/delete.js CHANGED
@@ -24,8 +24,8 @@ exports.command = function _delete(args) {
24
24
  }
25
25
  })
26
26
  .catch((error) => {
27
- if (args.debug) log.die("Failed to delete template", error.message, error.stack);
28
- else log.die("Failed to delete template", error.message);
27
+ if (args.debug) { log.die("Failed to delete template", error.message, error.stack); }
28
+ else { log.die("Failed to delete template", error.message); }
29
29
  });
30
30
  };
31
31
 
@@ -35,8 +35,10 @@ exports.command = function history(args) {
35
35
  if (args.full) {
36
36
  console.log(JSON.stringify(template_versions, null, 4));
37
37
  }
38
- else for (let tv of template_versions) {
39
- console.log(`[${tv.created}] ${template_id} ${tv.version}`);
38
+ else {
39
+ for (let tv of template_versions) {
40
+ console.log(`[${tv.created}] ${template_id} ${tv.version}`);
41
+ }
40
42
  }
41
43
  })
42
44
  .catch((error) => log.die("Failed to list template history", error.message, error.stack));
package/lib/cmd/list.js CHANGED
@@ -6,12 +6,12 @@ var log = require("../log"),
6
6
  sdk = require("../sdk");
7
7
 
8
8
  function byExternalIdAndVersion(a, b) {
9
- if (a.external_id < b.external_id) return -1;
10
- if (a.external_id > b.external_id) return +1;
9
+ if (a.external_id < b.external_id) { return -1; }
10
+ if (a.external_id > b.external_id) { return +1; }
11
11
 
12
- if (!a.version && !b.version) return 0;
13
- if (!a.version) return -1;
14
- if (!b.version) return +1;
12
+ if (!a.version && !b.version) { return 0; }
13
+ if (!a.version) { return -1; }
14
+ if (!b.version) { return +1; }
15
15
 
16
16
  return semver.cmp(semver.parse(a.version), semver.parse(b.version));
17
17
  }
@@ -45,12 +45,14 @@ exports.command = function list(args) {
45
45
  if (args.full) {
46
46
  console.log(JSON.stringify(templates, null, 4));
47
47
  }
48
- else for (let t of templates) {
49
- if (t.version) {
50
- console.log(t.external_id + " " + t.version);
51
- }
52
- else {
53
- console.log(t.external_id);
48
+ else {
49
+ for (let t of templates) {
50
+ if (t.version) {
51
+ console.log(t.external_id + " " + t.version);
52
+ }
53
+ else {
54
+ console.log(t.external_id);
55
+ }
54
56
  }
55
57
  }
56
58
  })
package/lib/cmd/login.js CHANGED
@@ -9,7 +9,7 @@ exports.command = function login(args) {
9
9
  function getEmail() {
10
10
  return new Promise(function(resolve, reject) {
11
11
  // If an email address was given on the command-line, use that
12
- if (args._[1]) return resolve(args._[1]);
12
+ if (args._[1]) { return resolve(args._[1]); }
13
13
 
14
14
  // Otherwise prompt for email address
15
15
  const input = readline.createInterface({ input: process.stdin, output: process.stdout });
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
  `;
@@ -20,7 +20,7 @@ function zipUpTemplate(template_dir, config) {
20
20
  // will close the wrong fd and cause chaos. Hence the
21
21
  // detachDescriptor: true option. (See kiln/flourish-sdk#40.)
22
22
  tmp.file({ detachDescriptor: true }, function(error, zip_filename, zip_fd) {
23
- if (error) return reject(error);
23
+ if (error) { return reject(error); }
24
24
 
25
25
  let zip = archiver.create("zip", {});
26
26
  zip.on("error", function(error) {
@@ -49,8 +49,8 @@ function zipUpTemplate(template_dir, config) {
49
49
  tour: JSON.stringify(config.tour),
50
50
  is_premium: config.is_premium,
51
51
  }), { name: "metadata.json" });
52
- if (config.settings) zip.append(JSON.stringify(config.settings), { name: "settings.js" });
53
- if (config.data) zip.append(JSON.stringify(config.data), { name: "data.json" });
52
+ if (config.settings) { zip.append(JSON.stringify(config.settings), { name: "settings.js" }); }
53
+ if (config.data) { zip.append(JSON.stringify(config.data), { name: "data.json" }); }
54
54
 
55
55
  const data_dir = path.join(template_dir, "data");
56
56
  if (fs.existsSync(data_dir)) {
@@ -59,7 +59,7 @@ function zipUpTemplate(template_dir, config) {
59
59
  const files = fs.readdirSync(data_dir).filter(d => d.endsWith(".csv"));
60
60
  for (const file of files) {
61
61
  let csv_text = fs.readFileSync(path.join(template_dir, "data", file), "utf8");
62
- if (csv_text.charAt(0) === "\uFEFF") csv_text = csv_text.substr(1);
62
+ if (csv_text.charAt(0) === "\uFEFF") { csv_text = csv_text.substr(1); }
63
63
  const parsed_csv = d3_dsv.csvParseRows(csv_text);
64
64
  column_types_by_sheet[file.replace(/\.csv$/, "")] = data_utils.getColumnTypesForData(parsed_csv);
65
65
  }
@@ -77,8 +77,8 @@ function zipUpTemplate(template_dir, config) {
77
77
  }
78
78
 
79
79
  for (let filename of sdk.TEMPLATE_SPECIAL_FILES) {
80
- if (filename == "template.yml") continue;
81
- if (filename == "README.md") continue;
80
+ if (filename == "template.yml") { continue; }
81
+ if (filename == "README.md") { continue; }
82
82
  let file_path = path.join(template_dir, filename);
83
83
  if (fs.existsSync(file_path)) {
84
84
  zip.file(file_path, { name: filename });
@@ -111,13 +111,13 @@ exports.command = function publish(args) {
111
111
 
112
112
  (args.build ? sdk.buildTemplate(template_dir, "production", "publish") : Promise.resolve())
113
113
  .then(() => {
114
- if (args.patch) return sdk.incrementPatchVersion(template_dir);
115
- if (args.prerelease) return sdk.incrementPrereleaseTag(template_dir);
116
- if (args.release) return sdk.removePrereleaseTag(template_dir);
114
+ if (args.patch) { return sdk.incrementPatchVersion(template_dir); }
115
+ if (args.prerelease) { return sdk.incrementPrereleaseTag(template_dir); }
116
+ if (args.release) { return sdk.removePrereleaseTag(template_dir); }
117
117
  })
118
118
  .then(() => sdk.readAndValidateConfig(template_dir))
119
- .then(({config, warnings}) => {
120
- if (!config.id) log.die("The template’s template.yml doesn’t have an id. Add one and try again.");
119
+ .then(({ config, warnings }) => {
120
+ if (!config.id) { log.die("The template’s template.yml doesn’t have an id. Add one and try again."); }
121
121
 
122
122
  if (config.id.indexOf("/") > -1) {
123
123
  return Promise.reject(new Error("Flourish no longer supports hard-coding a username in the id"));
@@ -163,8 +163,8 @@ exports.command = function publish(args) {
163
163
  });
164
164
  })
165
165
  .catch((error) => {
166
- if (args.debug) log.die("Failed to upload template", error.message, error.stack);
167
- else log.die("Failed to upload template", error.message);
166
+ if (args.debug) { log.die("Failed to upload template", error.message, error.stack); }
167
+ else { log.die("Failed to upload template", error.message); }
168
168
  });
169
169
  };
170
170
 
@@ -17,12 +17,12 @@ exports.command = function register(args) {
17
17
  return new Promise(function(resolve, reject) {
18
18
  read({ prompt: "Password: ", silent: true }).then((pw_i) => {
19
19
  read({ prompt: "Confirm password: ", silent: true }).then((pw_ii) => {
20
- if (pw_i === pw_ii) return resolve(pw_i);
20
+ if (pw_i === pw_ii) { return resolve(pw_i); }
21
21
 
22
22
  log.warn("Passwords not the same! Try again.");
23
23
 
24
24
  read({ prompt: "Confirm password: ", silent: true }).then((pw_iii) => {
25
- if (pw_i === pw_iii) return resolve(pw_i);
25
+ if (pw_i === pw_iii) { return resolve(pw_i); }
26
26
  reject(new Error("Passwords still don’t match. Exiting."));
27
27
  })
28
28
  .catch(reject);
@@ -88,7 +88,7 @@ exports.command = function register(args) {
88
88
  function agreeTerms() {
89
89
  return askAboutTerms()
90
90
  .then((agreed) => {
91
- if (!agreed) return Promise.reject(new Error("You must agree to the Terms and Conditions"));
91
+ if (!agreed) { return Promise.reject(new Error("You must agree to the Terms and Conditions")); }
92
92
  });
93
93
  }
94
94
 
package/lib/cmd/run.js CHANGED
@@ -18,13 +18,13 @@ exports.command = function run(args) {
18
18
  listen: args.listen,
19
19
  open: args.open,
20
20
  debug: args.debug,
21
- host: args.host
21
+ host: args.host,
22
22
  });
23
23
  }
24
24
 
25
25
  fs.stat(template_dir, function(error, stat) {
26
- if (error) log.die(`Could not access ${template_dir}: ${error.message}`);
27
- if (!stat.isDirectory()) log.die(`Not a directory: ${template_dir}`);
26
+ if (error) { log.die(`Could not access ${template_dir}: ${error.message}`); }
27
+ if (!stat.isDirectory()) { log.die(`Not a directory: ${template_dir}`); }
28
28
 
29
29
  if (!fs.existsSync(path.join(template_dir, "template.yml"))) {
30
30
  if (fs.existsSync(path.join(template_dir, "settings.js"))) {
@@ -20,15 +20,15 @@ function loadFile(path_parts, options) {
20
20
  }
21
21
 
22
22
  function succeed(result) {
23
- if (!options.silentSuccess) log.success(`Loaded ${filename}`);
23
+ if (!options.silentSuccess) { log.success(`Loaded ${filename}`); }
24
24
  resolve(result);
25
25
  }
26
26
 
27
27
  fs.readFile(file_path, "utf8", function(error, loaded_text) {
28
- if (error && error.code === "ENOENT") return resolve(null);
29
- else if (error) return fail(`Failed to load ${file_path}`, error);
28
+ if (error && error.code === "ENOENT") { return resolve(null); }
29
+ else if (error) { return fail(`Failed to load ${file_path}`, error); }
30
30
 
31
- if (!options.json) return succeed(loaded_text);
31
+ if (!options.json) { return succeed(loaded_text); }
32
32
 
33
33
  try { succeed(JSON.parse(loaded_text)); }
34
34
  catch (error) {
@@ -41,8 +41,8 @@ function loadFile(path_parts, options) {
41
41
  function deleteIfExists(file_path) {
42
42
  return new Promise(function(resolve, reject) {
43
43
  fs.unlink(file_path, function(error) {
44
- if (error && error.code !== "ENOENT") return reject(error);
45
- if (!error) log.success("Deleted " + file_path);
44
+ if (error && error.code !== "ENOENT") { return reject(error); }
45
+ if (!error) { log.success("Deleted " + file_path); }
46
46
  resolve();
47
47
  });
48
48
  });
@@ -59,7 +59,7 @@ exports.upgrade = function upgrade(template_dir) {
59
59
  })
60
60
  .then((settings) => {
61
61
  for (let s of settings) {
62
- if (typeof s === "object") delete s.validate;
62
+ if (typeof s === "object") { delete s.validate; }
63
63
  }
64
64
  return settings;
65
65
  });
@@ -78,7 +78,7 @@ exports.upgrade = function upgrade(template_dir) {
78
78
  return Promise.all([
79
79
  loadMetadata(),
80
80
  loadSettings(),
81
- loadTemplateDataBindings()
81
+ loadTemplateDataBindings(),
82
82
  ])
83
83
  .then(([metadata, settings, data_bindings]) => {
84
84
  const o = {
@@ -88,9 +88,9 @@ exports.upgrade = function upgrade(template_dir) {
88
88
 
89
89
  sdk_version: sdk.SDK_MAJOR_VERSION,
90
90
 
91
- settings: settings
91
+ settings: settings,
92
92
  };
93
- if (data_bindings) o.data = data_bindings;
93
+ if (data_bindings) { o.data = data_bindings; }
94
94
  return yaml.safeDump(o);
95
95
  });
96
96
  }
@@ -98,14 +98,14 @@ exports.upgrade = function upgrade(template_dir) {
98
98
  function deleteOldFiles() {
99
99
  return Promise.all(
100
100
  ["settings.js", "metadata.json", "data.json"]
101
- .map((filename) => deleteIfExists(path.join(template_dir, filename)))
101
+ .map((filename) => deleteIfExists(path.join(template_dir, filename))),
102
102
  );
103
103
  }
104
104
 
105
105
  return new Promise(function(resolve, reject) {
106
106
  fs.stat(template_dir, function(error, stat) {
107
- if (error) reject(new Error(`Could not access ${template_dir}: ${error.message}`));
108
- if (!stat.isDirectory()) reject(new Error(`Not a directory: ${template_dir}`));
107
+ if (error) { reject(new Error(`Could not access ${template_dir}: ${error.message}`)); }
108
+ if (!stat.isDirectory()) { reject(new Error(`Not a directory: ${template_dir}`)); }
109
109
 
110
110
  const template_yml_file = path.join(template_dir, "template.yml");
111
111
  if (fs.existsSync(template_yml_file)) {
@@ -117,7 +117,7 @@ exports.upgrade = function upgrade(template_dir) {
117
117
  generateTemplateYaml()
118
118
  .then((template_yml) => new Promise(function(resolve, reject) {
119
119
  fs.writeFile(template_yml_file, template_yml, function(error) {
120
- if (error) return reject(error);
120
+ if (error) { return reject(error); }
121
121
  log.success("Wrote template.yml");
122
122
  resolve();
123
123
  });
@@ -18,8 +18,8 @@ function convert(html) {
18
18
  exports.upgrade = function upgrade(template_dir) {
19
19
  return new Promise(function(resolve, reject) {
20
20
  fs.stat(template_dir, function(error, stat) {
21
- if (error) reject(new Error(`Could not access ${template_dir}: ${error.message}`));
22
- if (!stat.isDirectory()) reject(new Error(`Not a directory: ${template_dir}`));
21
+ if (error) { reject(new Error(`Could not access ${template_dir}: ${error.message}`)); }
22
+ if (!stat.isDirectory()) { reject(new Error(`Not a directory: ${template_dir}`)); }
23
23
 
24
24
  const index_html_file = path.join(template_dir, "index.html");
25
25
  if (!fs.existsSync(index_html_file)) {
@@ -28,11 +28,11 @@ exports.upgrade = function upgrade(template_dir) {
28
28
  }
29
29
 
30
30
  fs.readFile(index_html_file, "utf8", function(error, contents) {
31
- if (error) return reject(error);
31
+ if (error) { return reject(error); }
32
32
 
33
33
  var new_contents = convert(contents);
34
34
  fs.writeFile(index_html_file, new_contents, function(error) {
35
- if (error) return reject(error);
35
+ if (error) { return reject(error); }
36
36
  resolve(true);
37
37
  });
38
38
  });
@@ -9,8 +9,8 @@ function addBuildRules(config) {
9
9
  javascript: {
10
10
  script: "npm run build",
11
11
  directory: "src",
12
- files: ["package.json", "rollup.config.js"]
13
- }
12
+ files: ["package.json", "rollup.config.js"],
13
+ },
14
14
  };
15
15
  return config;
16
16
  }
@@ -18,12 +18,12 @@ function addBuildRules(config) {
18
18
  exports.upgrade = function upgrade(template_dir) {
19
19
  return new Promise(function(resolve, reject) {
20
20
  fs.stat(template_dir, function(error, stat) {
21
- if (error) reject(new Error(`Could not access ${template_dir}: ${error.message}`));
22
- if (!stat.isDirectory()) reject(new Error(`Not a directory: ${template_dir}`));
21
+ if (error) { reject(new Error(`Could not access ${template_dir}: ${error.message}`)); }
22
+ if (!stat.isDirectory()) { reject(new Error(`Not a directory: ${template_dir}`)); }
23
23
 
24
24
  sdk.readConfig(template_dir)
25
25
  .then((config) => {
26
- if ("build" in config) return false;
26
+ if ("build" in config) { return false; }
27
27
  return sdk.writeConfig(template_dir, addBuildRules(config))
28
28
  .then(() => true);
29
29
  })
@@ -6,12 +6,12 @@ var fs = require("fs"),
6
6
  exports.upgrade = function upgrade(template_dir) {
7
7
  return new Promise(function(resolve, reject) {
8
8
  fs.stat(template_dir, function(error, stat) {
9
- if (error) return reject(new Error(`Could not access ${template_dir}: ${error.message}`));
10
- if (!stat.isDirectory()) return reject(new Error(`Not a directory: ${template_dir}`));
9
+ if (error) { return reject(new Error(`Could not access ${template_dir}: ${error.message}`)); }
10
+ if (!stat.isDirectory()) { return reject(new Error(`Not a directory: ${template_dir}`)); }
11
11
 
12
12
  sdk.readConfig(template_dir)
13
13
  .then((config) => {
14
- if (config.sdk_version == 3) return false;
14
+ if (config.sdk_version == 3) { return false; }
15
15
  delete config.autoheight;
16
16
  config.sdk_version = 3;
17
17
  return sdk.writeConfig(template_dir, config)
@@ -14,8 +14,8 @@ function runUpgrade({ upgrade, title }, template_dir) {
14
14
 
15
15
  return upgrade(template_dir)
16
16
  .then((upgraded) => {
17
- if (upgraded) log.success("Upgrade successful");
18
- else log.info("Upgrade not needed");
17
+ if (upgraded) { log.success("Upgrade successful"); }
18
+ else { log.info("Upgrade not needed"); }
19
19
 
20
20
  return upgraded;
21
21
  });
@@ -24,12 +24,12 @@ function runUpgrade({ upgrade, title }, template_dir) {
24
24
  let upgrade_index = 0;
25
25
  function runUpgrades(template_dir, num_run=0) {
26
26
  const upgrade = upgrades[upgrade_index];
27
- if (!upgrade) return Promise.resolve(num_run);
27
+ if (!upgrade) { return Promise.resolve(num_run); }
28
28
 
29
29
  return runUpgrade(upgrade, template_dir)
30
30
  .then((upgraded) => {
31
31
  upgrade_index += 1;
32
- if (upgraded) num_run += 1;
32
+ if (upgraded) { num_run += 1; }
33
33
  })
34
34
  .then(() => runUpgrades(template_dir, num_run));
35
35
  }
@@ -44,8 +44,8 @@ exports.command = function upgrade(args) {
44
44
  }
45
45
  })
46
46
  .catch((error) => {
47
- if (args.debug) log.problem("Upgrade failed", error.message, error.stack);
48
- else log.problem("Upgrade failed", error.message);
47
+ if (args.debug) { log.problem("Upgrade failed", error.message, error.stack); }
48
+ else { log.problem("Upgrade failed", error.message); }
49
49
  });
50
50
  };
51
51
 
package/lib/common.js CHANGED
@@ -2,7 +2,7 @@ const deepCopyObject = require("../common/utils/state").deepCopyObject;
2
2
 
3
3
 
4
4
  function isPrimitive(entity) {
5
- if (entity === null) return true;
5
+ if (entity === null) { return true; }
6
6
  return [ "string", "boolean", "number" ].includes(typeof entity);
7
7
  }
8
8
 
@@ -10,19 +10,23 @@ function isPrimitive(entity) {
10
10
  function extendItem(extendee, extender) {
11
11
  const v = isPrimitive(extendee) ? [extendee] : extendee;
12
12
  const w = isPrimitive(extender) ? [extender] : extender;
13
- const CANNOT_MERGE_MESSAGE = `template.yml: cannot extend ${extendee} with ${extender}`;
13
+ const CANNOT_MERGE_MESSAGE = `template.yml: cannot extend ${
14
+ JSON.stringify(extendee, null, 2)
15
+ } with ${
16
+ JSON.stringify(extender, null, 2)
17
+ }`;
14
18
  let output;
15
19
 
16
20
  if (Array.isArray(v)) {
17
- if (Array.isArray(w)) output = v.concat(w);
18
- else throw new Error(CANNOT_MERGE_MESSAGE);
21
+ if (Array.isArray(w)) { output = v.concat(w); }
22
+ else { throw new Error(CANNOT_MERGE_MESSAGE); }
19
23
  }
20
24
  else if (typeof v === "object") {
21
25
  // Order of Object.assign means parameters in extendee are favoured over parameters in extender
22
- if (typeof(w) === "object") output = Object.assign(deepCopyObject(w), deepCopyObject(v));
23
- else throw new Error(CANNOT_MERGE_MESSAGE);
26
+ if (typeof(w) === "object") { output = Object.assign(deepCopyObject(w), deepCopyObject(v)); }
27
+ else { throw new Error(CANNOT_MERGE_MESSAGE); }
24
28
  }
25
- else throw new Error(CANNOT_MERGE_MESSAGE);
29
+ else { throw new Error(CANNOT_MERGE_MESSAGE); }
26
30
 
27
31
  return output;
28
32
  }
package/lib/log.js CHANGED
@@ -3,22 +3,22 @@
3
3
  const pc = require("picocolors");
4
4
 
5
5
  function victory(...lines) {
6
- for (let line of lines) console.log(pc.bold(pc.green("👻 " + line)));
6
+ for (let line of lines) { console.log(pc.bold(pc.green("👻 " + line))); }
7
7
  }
8
8
  function success(...lines) {
9
- for (let line of lines) console.log(pc.green(" " + line));
9
+ for (let line of lines) { console.log(pc.green(" " + line)); }
10
10
  }
11
11
  function info(...lines) {
12
- for (let line of lines) console.log(pc.yellow(" " + line));
12
+ for (let line of lines) { console.log(pc.yellow(" " + line)); }
13
13
  }
14
14
  function warn(...lines) {
15
- for (let line of lines) console.warn(pc.yellow("⚠️ " + line));
15
+ for (let line of lines) { console.warn(pc.yellow("⚠️ " + line)); }
16
16
  }
17
17
  function warn_bold(...lines) {
18
- for (let line of lines) console.warn(pc.bold(pc.yellow(" " + line)));
18
+ for (let line of lines) { console.warn(pc.bold(pc.yellow(" " + line))); }
19
19
  }
20
20
  function problem(...lines) {
21
- for (let line of lines) console.error(pc.red("😱 " + line));
21
+ for (let line of lines) { console.error(pc.red("😱 " + line)); }
22
22
  }
23
23
 
24
24
  function die(...lines) {
@@ -27,5 +27,5 @@ function die(...lines) {
27
27
  }
28
28
 
29
29
  module.exports = {
30
- victory, success, info, warn, warn_bold, problem, die
30
+ victory, success, info, warn, warn_bold, problem, die,
31
31
  };