powerbi-visuals-tools 4.3.2 → 5.0.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 (69) hide show
  1. package/Changelog.md +7 -0
  2. package/README.md +1 -1
  3. package/bin/pbiviz.js +55 -36
  4. package/certs/PowerBICustomVisualTest_private.key +26 -26
  5. package/certs/PowerBICustomVisualTest_public.crt +17 -17
  6. package/config.json +27 -34
  7. package/lib/CertificateTools.js +119 -143
  8. package/lib/CommandManager.js +52 -0
  9. package/lib/ConsoleWriter.js +63 -85
  10. package/lib/TemplateFetcher.js +23 -30
  11. package/lib/VisualGenerator.js +42 -56
  12. package/lib/VisualManager.js +193 -0
  13. package/lib/WebPackWrap.js +96 -145
  14. package/lib/utils.js +21 -13
  15. package/lib/webpack.config.js +47 -56
  16. package/package.json +34 -26
  17. package/spec/clean-tests.js +1 -1
  18. package/spec/e2e/pbivizCertSpec.js +14 -13
  19. package/spec/e2e/pbivizInfoSpec.js +7 -10
  20. package/spec/e2e/pbivizNewSpec.js +53 -65
  21. package/spec/e2e/pbivizPackageSpec.js +86 -90
  22. package/spec/e2e/pbivizStartSpec.js +6 -7
  23. package/spec/e2e/pbivizWebpackVerSpec.js +14 -16
  24. package/spec/e2e/{utils.js → testUtils.js} +9 -12
  25. package/spec/helpers/FileSystem.js +18 -18
  26. package/spec/jasmine-runner.js +5 -5
  27. package/src/CertificateTools.ts +431 -0
  28. package/src/CommandManager.ts +78 -0
  29. package/src/ConsoleWriter.ts +206 -0
  30. package/src/TemplateFetcher.ts +122 -0
  31. package/src/VisualGenerator.ts +236 -0
  32. package/src/VisualManager.ts +220 -0
  33. package/src/WebPackWrap.ts +299 -0
  34. package/src/utils.ts +41 -0
  35. package/src/webpack.config.ts +144 -0
  36. package/templates/pbiviz-json-template.js +2 -2
  37. package/templates/pbiviz.json.template +1 -1
  38. package/templates/plugin-ts-template.js +1 -1
  39. package/templates/visuals/default/.eslintignore +5 -0
  40. package/templates/visuals/default/.eslintrc.js +20 -0
  41. package/templates/visuals/default/package.json +9 -8
  42. package/templates/visuals/default/pbiviz.json +3 -2
  43. package/templates/visuals/default/tsconfig.json +2 -2
  44. package/templates/visuals/rhtml/.eslintignore +5 -0
  45. package/templates/visuals/rhtml/.eslintrc.js +20 -0
  46. package/templates/visuals/rhtml/package.json +7 -6
  47. package/templates/visuals/rhtml/pbiviz.json +2 -1
  48. package/templates/visuals/rvisual/.eslintignore +5 -0
  49. package/templates/visuals/rvisual/.eslintrc.js +20 -0
  50. package/templates/visuals/rvisual/package.json +5 -4
  51. package/templates/visuals/slicer/.eslintignore +5 -0
  52. package/templates/visuals/slicer/.eslintrc.js +20 -0
  53. package/templates/visuals/slicer/package.json +8 -7
  54. package/templates/visuals/table/.eslintignore +5 -0
  55. package/templates/visuals/table/.eslintrc.js +20 -0
  56. package/templates/visuals/table/package.json +8 -7
  57. package/templates/visuals/table/tsconfig.json +4 -0
  58. package/tsconfig.json +22 -0
  59. package/bin/pbiviz-info.js +0 -54
  60. package/bin/pbiviz-new.js +0 -82
  61. package/bin/pbiviz-package.js +0 -122
  62. package/bin/pbiviz-start.js +0 -142
  63. package/lib/CommandHelpManager.js +0 -51
  64. package/lib/VisualPackage.js +0 -118
  65. package/templates/visuals/default/tslint.json +0 -9
  66. package/templates/visuals/rhtml/tslint.json +0 -9
  67. package/templates/visuals/rvisual/tslint.json +0 -9
  68. package/templates/visuals/slicer/tslint.json +0 -9
  69. package/templates/visuals/table/tslint.json +0 -9
@@ -23,76 +23,64 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
24
  * THE SOFTWARE.
25
25
  */
26
-
27
26
  "use strict";
28
-
29
- let chalk = require('chalk');
30
- let fs = require('fs');
31
- let path = require('path');
32
- let os = require('os');
33
-
34
- if (os.platform() === 'darwin') {
35
- chalk = chalk.bold;
36
- }
37
-
27
+ import chalk from 'chalk';
28
+ import fs from 'fs';
29
+ import os from 'os';
30
+ import path from 'path';
31
+ import { getRootPath } from './utils.js';
32
+ const preferredChalk = os.platform() === 'darwin' ? chalk.bold : chalk;
38
33
  function prependLogTag(tag, args) {
39
- return [tag].concat(Array.from(args));
34
+ return [tag].concat(args);
40
35
  }
41
-
42
- class ConsoleWriter {
36
+ export default class ConsoleWriter {
43
37
  /** Causes the terminal to beep */
44
38
  static beep() {
45
39
  process.stdout.write("\x07");
46
40
  }
47
-
48
41
  /** Outputs a blank line */
49
42
  static blank() {
50
- console.info(chalk.reset(' '));
43
+ console.info(preferredChalk.reset(' '));
51
44
  }
52
-
53
45
  /**
54
46
  * Outputs arguments with the "done" tag / colors
55
- *
56
- * @param {...*} arguments - arguments passed through to console.info
47
+ *
48
+ * @param {array} arguments - arguments passed through to console.info
57
49
  */
58
- static done(/* arguments */) {
59
- let tag = chalk.bgGreen(' done ');
60
- console.info.apply(this, prependLogTag(tag, arguments));
50
+ static done(args) {
51
+ const tag = preferredChalk.bgGreen(' done ');
52
+ console.info.apply(this, prependLogTag(tag, args));
61
53
  }
62
-
63
54
  /**
64
55
  * Outputs arguments with the "info" tag / colors
65
- *
66
- * @param {...*} arguments - arguments passed through to console.info
56
+ *
57
+ * @param {array} args - arguments passed through to console.info
67
58
  */
68
- static info(/* arguments */) {
69
- let tag = chalk.bgCyan(' info ');
70
- console.info.apply(this, prependLogTag(tag, arguments));
59
+ static info(args) {
60
+ const tag = preferredChalk.bgCyan(' info ');
61
+ console.info.apply(this, prependLogTag(tag, args));
71
62
  }
72
-
73
63
  /**
74
64
  * Outputs arguments with the "warn" tag / colors
75
- *
76
- * @param {...*} arguments - arguments passed through to console.warn
65
+ *
66
+ * @param {array} args - arguments passed through to console.warn
77
67
  */
78
- static warn(/* arguments */) {
79
- let tag = chalk.bgYellow.black(' warn ');
80
- console.warn.apply(this, prependLogTag(tag, arguments));
68
+ static warning(args) {
69
+ const tag = preferredChalk.bgYellow.black(' warn ');
70
+ console.warn.apply(this, prependLogTag(tag, args));
81
71
  }
82
-
83
72
  /**
84
73
  * Outputs arguments with the "error" tag / colors
85
- *
86
- * @param {...*} arguments - arguments passed through to console.error
74
+ *
75
+ * @param {array} args - arguments passed through to console.error
87
76
  */
88
- static error(/* arguments */) {
89
- let tag = chalk.bgRed(' error ');
90
- console.error.apply(this, prependLogTag(tag, arguments));
77
+ static error(args) {
78
+ const tag = preferredChalk.bgRed(' error ');
79
+ console.error.apply(this, prependLogTag(tag, args));
91
80
  }
92
-
93
81
  /**
94
82
  * Outputs an object as a table
95
- *
83
+ *
96
84
  * @param {string} data - object to output
97
85
  * @param {number} [depthLimit=Infinity] - limit the number of levels to recurse
98
86
  * @param {string} [keyPrefix=''] - text to prepend to each key
@@ -101,35 +89,34 @@ class ConsoleWriter {
101
89
  if (!data) {
102
90
  return;
103
91
  }
104
- let limit = typeof depthLimit === 'undefined' ? Infinity : depthLimit;
105
- for (let key in data) {
106
- let item = data[key];
107
- let itemKey = (keyPrefix || '') + key;
92
+ const limit = typeof depthLimit === 'undefined' ? Infinity : depthLimit;
93
+ for (const key in data) {
94
+ const item = data[key];
95
+ const itemKey = (keyPrefix || '') + key;
108
96
  if (limit > 1 && typeof item === 'object' && !Array.isArray(item)) {
109
97
  ConsoleWriter.infoTable(item, limit - 1, itemKey + '.');
110
- } else {
98
+ }
99
+ else {
111
100
  ConsoleWriter.infoTableRow(itemKey, item);
112
101
  }
113
102
  }
114
103
  }
115
-
116
104
  /**
117
105
  * Outputs a table row with even spaced keys
118
- *
106
+ *
119
107
  * @param {string} key - title of this row
120
108
  * @param {string} value - value for this row
121
109
  * @param {number} [keyWidth=30] - width used for padding of the key column
122
110
  */
123
111
  static infoTableRow(key, value, keyWidth) {
124
- let width = keyWidth || 30;
125
- let padding = Math.max(0, width - key.length);
126
- let paddedKey = chalk.bold(key) + (new Array(padding)).join('.');
127
- ConsoleWriter.info(paddedKey, value);
112
+ const width = keyWidth || 30;
113
+ const padding = Math.max(0, width - key.length);
114
+ const paddedKey = preferredChalk.bold(key) + (new Array(padding)).join('.');
115
+ ConsoleWriter.info([paddedKey, value]);
128
116
  }
129
-
130
117
  /**
131
118
  * Outputs formatted errors
132
- *
119
+ *
133
120
  * @param {Array<Error>} errors
134
121
  */
135
122
  static formattedErrors(errors) {
@@ -138,58 +125,53 @@ class ConsoleWriter {
138
125
  if (!error) {
139
126
  return;
140
127
  }
141
- let tag = error.type ? chalk.bold(error.type.toUpperCase()) : 'UNKNOWN';
142
- let file = error.filename ? chalk.bgWhite.black(` ${error.filename} `) + ':' : '';
143
- let position = (error.line && error.column) ? chalk.cyan(`(${error.line},${error.column})`) : '';
144
- let message = error.message || '';
145
- ConsoleWriter.error(tag, `${file} ${position} ${message}`);
128
+ const tag = error.type ? preferredChalk.bold(error.type.toUpperCase()) : 'UNKNOWN';
129
+ const file = error.filename ? preferredChalk.bgWhite.black(` ${error.filename} `) + ':' : '';
130
+ const position = (error.line && error.column) ? preferredChalk.cyan(`(${error.line},${error.column})`) : '';
131
+ const message = error.message || '';
132
+ ConsoleWriter.error([tag, `${file} ${position} ${message}`]);
146
133
  });
147
- } else {
148
- ConsoleWriter.error('UNKNOWN', errors);
134
+ }
135
+ else {
136
+ ConsoleWriter.error(['UNKNOWN', errors]);
149
137
  }
150
138
  }
151
-
152
139
  /**
153
140
  * Outputs ascii art of the PowerBI logo
154
141
  */
155
- static logo() {
156
- let logoText = fs.readFileSync(path.join(__dirname, '..', 'assets', 'logo.txt')).toString();
157
- console.info(chalk.bold.yellow(logoText));
142
+ static getLogoVisualization() {
143
+ return fs.readFileSync(path.join(getRootPath(), 'assets', 'logo.txt')).toString();
158
144
  }
159
-
160
145
  /**
161
146
  * Outputs validation log from PBIVIZ package checking
162
147
  */
163
148
  static validationLog(log) {
164
-
165
149
  // api/js/css/pkg
166
- let filterChecks = (attrCB, propCB) => {
167
- for (let checkname in log) {
150
+ const filterChecks = (attrCB, propCB) => {
151
+ for (const checkname in log) {
168
152
  if (checkname !== 'valid') {
169
- let checkpoint = log[checkname];
153
+ const checkpoint = log[checkname];
170
154
  ConsoleWriter[checkpoint.error.length ? 'info' : 'done'](checkpoint.check);
171
155
  attrCB(checkpoint, propCB);
172
156
  }
173
157
  }
174
158
  };
175
-
176
159
  // error/message/ok
177
- let filterCheckAttrs = (checkpoint, propCB) => {
178
- for (let propName in checkpoint) {
160
+ const filterCheckAttrs = (checkpoint, propCB) => {
161
+ for (const propName in checkpoint) {
179
162
  if (propName !== 'message') {
180
- let prop = checkpoint[propName];
163
+ const prop = checkpoint[propName];
181
164
  if (typeof (prop) === 'object' && prop.length) {
182
165
  propCB(prop, propName);
183
166
  }
184
167
  }
185
168
  }
186
169
  };
187
-
188
170
  // col/line/text
189
- let filterAttrProps = (props, propName) => {
171
+ const filterAttrProps = (props, propName) => {
190
172
  props.forEach((opt) => {
191
- let result = [];
192
- for (let key in opt) {
173
+ const result = [];
174
+ for (const key in opt) {
193
175
  result.push(opt[key]);
194
176
  }
195
177
  if (result.length) {
@@ -197,14 +179,10 @@ class ConsoleWriter {
197
179
  }
198
180
  });
199
181
  };
200
-
201
182
  filterChecks(filterCheckAttrs, filterAttrProps);
202
-
203
- let type = log.valid ? 'done' : 'error';
204
- let text = log.valid ? 'Valid package' : 'Invalid package';
183
+ const type = log.valid ? 'done' : 'error';
184
+ const text = log.valid ? 'Valid package' : 'Invalid package';
205
185
  ConsoleWriter.blank();
206
186
  ConsoleWriter[type](text);
207
187
  }
208
188
  }
209
-
210
- module.exports = ConsoleWriter;
@@ -1,23 +1,24 @@
1
- const fs = require('fs-extra');
2
- const path = require('path');
3
- const config = require('../config.json');
4
- const JSZip = require('jszip');
5
- const VisualGenerator = require("./VisualGenerator");
6
- const { exec } = require('child_process');
7
- const ConsoleWriter = require('../lib/ConsoleWriter');
8
- const download = require('./utils').download;
9
- const createFolder = require('./utils').createFolder;
10
-
11
- class TemplateFetcher {
12
- constructor({ templateName, visualName, apiVersion }) {
1
+ import { createFolder, download, readJsonFromRoot } from './utils.js';
2
+ import ConsoleWriter from './ConsoleWriter.js';
3
+ import JSZip from 'jszip';
4
+ import VisualGenerator from "./VisualGenerator.js";
5
+ import { exec } from 'child_process';
6
+ import fs from 'fs-extra';
7
+ import path from 'path';
8
+ const config = readJsonFromRoot('config.json');
9
+ export default class TemplateFetcher {
10
+ templateName;
11
+ visualName;
12
+ folderName;
13
+ apiVersion;
14
+ constructor(templateName, visualName, apiVersion) {
13
15
  this.templateName = templateName;
14
16
  this.visualName = visualName;
15
17
  this.folderName = `${this.visualName}`;
16
18
  this.apiVersion = apiVersion;
17
19
  }
18
-
19
20
  fetch() {
20
- let folder = createFolder.call(this, this.folderName);
21
+ const folder = createFolder.call(this, this.folderName);
21
22
  download.call(this, config.visualTemplates[this.templateName], path.join(folder, "template.zip"))
22
23
  .then(this.extractFiles.bind(this))
23
24
  .then(this.removeZipFile.bind(this))
@@ -26,37 +27,34 @@ class TemplateFetcher {
26
27
  .then(this.runNpmInstall.bind(this))
27
28
  .then(this.showNextSteps.bind(this));
28
29
  }
29
-
30
30
  async removeZipFile() {
31
31
  const folder = path.join("./", this.folderName);
32
32
  const fileName = path.join(folder, "template.zip");
33
33
  await fs.unlink(`.${path.sep}${fileName}`, (err) => {
34
34
  if (err) {
35
- ConsoleWriter.warn(`.${path.sep}${fileName} was not deleted`);
35
+ ConsoleWriter.warning(`.${path.sep}${fileName} was not deleted`);
36
36
  }
37
37
  });
38
38
  }
39
-
40
39
  async extractFiles(file) {
41
40
  const filePath = path.join(process.cwd(), file.path);
42
41
  const buffer = await fs.readFile(filePath);
43
42
  const zip = await JSZip.loadAsync(buffer);
44
-
45
43
  const filesList = Object.keys(zip.files);
46
44
  for (const filename of filesList) {
47
45
  if (filename[filename.length - 1] === "/") {
48
46
  // generate folders for exclude parent folder
49
47
  const dest = path.join(path.dirname(filePath), path.join(filename, ".."));
50
48
  await fs.ensureDir(dest);
51
- } else {
49
+ }
50
+ else {
52
51
  // write files into dirs for exclude parent folder
53
- const dest = path.join(path.dirname(filePath), path.join(path.dirname(filename), "..", filename.split("/").pop(0)));
54
- const content = await zip.file(filename).async('nodebuffer');
52
+ const dest = path.join(path.dirname(filePath), path.join(path.dirname(filename), "..", filename.split("/").pop() ?? ""));
53
+ const content = await zip.file(filename)?.async('nodebuffer');
55
54
  await fs.writeFile(dest, content);
56
55
  }
57
56
  }
58
57
  }
59
-
60
58
  async setApiVersion() {
61
59
  if (!this.apiVersion) {
62
60
  return;
@@ -72,14 +70,12 @@ class TemplateFetcher {
72
70
  }
73
71
  await fs.writeJSON(packageJsonFile, packageJson);
74
72
  }
75
-
76
73
  async setVisualGUID() {
77
74
  const pbivizJsonFile = path.join(process.cwd(), this.folderName, "pbiviz.json");
78
75
  const pbivizJson = await fs.readJson(pbivizJsonFile);
79
76
  pbivizJson.visual.guid = this.visualName + VisualGenerator.generateVisualGuid();
80
77
  await fs.writeJSON(pbivizJsonFile, pbivizJson);
81
78
  }
82
-
83
79
  runNpmInstall() {
84
80
  return new Promise((resolve, reject) => {
85
81
  ConsoleWriter.info("Installing packages...");
@@ -91,12 +87,12 @@ class TemplateFetcher {
91
87
  ConsoleWriter.error(`Error code: ${error.code}`);
92
88
  ConsoleWriter.error(`Signal received: ${error.signal}`);
93
89
  }
94
- ConsoleWriter.warn(stderr);
90
+ ConsoleWriter.warning(stderr);
95
91
  ConsoleWriter.info(stdout);
96
- resolve();
92
+ resolve(true);
97
93
  });
98
94
  child.on("error", (er) => {
99
- ConsoleWriter.log(er);
95
+ ConsoleWriter.error(er);
100
96
  reject();
101
97
  });
102
98
  child.on("exit", (code) => {
@@ -107,12 +103,9 @@ class TemplateFetcher {
107
103
  });
108
104
  });
109
105
  }
110
-
111
106
  showNextSteps() {
112
107
  ConsoleWriter.blank();
113
108
  ConsoleWriter.info("Run `npm run start` to start visual development");
114
109
  ConsoleWriter.info("Run `npm run package` to create visual package");
115
110
  }
116
111
  }
117
-
118
- module.exports = TemplateFetcher;
@@ -23,21 +23,18 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
24
  * THE SOFTWARE.
25
25
  */
26
-
27
26
  "use strict";
28
-
29
- const fs = require('fs-extra');
30
- const path = require('path');
31
- const uuid = require('uuid');
32
- const compareVersions = require("compare-versions");
33
- const config = require('../config.json');
34
- const lodashDefaults = require('lodash.defaults');
35
- const template = require('../templates/pbiviz-json-template');
36
-
37
- const VISUAL_TEMPLATES_PATH = path.join(__dirname, '..', config.templates.visuals);
27
+ import crypto from 'crypto';
28
+ import { getRootPath, readJsonFromRoot } from './utils.js';
29
+ import { compareVersions } from "compare-versions";
30
+ import fs from 'fs-extra';
31
+ import lodashDefaults from 'lodash.defaults';
32
+ import path from 'path';
33
+ import template from '../templates/pbiviz-json-template.js';
34
+ const config = readJsonFromRoot('config.json');
35
+ const VISUAL_TEMPLATES_PATH = path.join(getRootPath(), config.templates.visuals);
38
36
  const API_VERSION = config.generate.apiVersion;
39
37
  const minAPIversion = config.constants.minAPIversion;
40
-
41
38
  /**
42
39
  * Generates the data for the visual
43
40
  */
@@ -51,9 +48,8 @@ function generateVisualOptions(visualName, apiVersion) {
51
48
  apiVersion: apiVersion
52
49
  };
53
50
  }
54
-
55
51
  /**
56
- *
52
+ *
57
53
  */
58
54
  function generateVisualName(displayName) {
59
55
  return displayName.replace(/(?:^\w|[A-Z]|\b\w|_|\s+)/g, (match, index) => {
@@ -63,58 +59,51 @@ function generateVisualName(displayName) {
63
59
  return index === 0 ? match.toLowerCase() : match.toUpperCase();
64
60
  });
65
61
  }
66
-
67
62
  /**
68
63
  * Creates a default pbiviz.json config file
69
- *
64
+ *
70
65
  * @param {string} visualPath - path to the visual
71
66
  * @param {Object} options - visual information for populating the pbiviz.json template
72
67
  * @param {string} templateName - external js files
73
68
  */
74
69
  function createPbiVizJson(visualPath, options, templateName) {
75
-
76
70
  // read the global template data
77
71
  // and generate the actual file content
78
72
  let data = template(options);
79
-
80
73
  // write out the target file content
81
- let targetPath = path.join(visualPath, 'pbiviz.json');
74
+ const targetPath = path.join(visualPath, 'pbiviz.json');
82
75
  fs.writeFileSync(targetPath, data);
83
-
84
76
  let templatePath = path.join(VISUAL_TEMPLATES_PATH, templateName);
85
77
  templatePath = path.join(templatePath, 'pbiviz.json');
86
78
  if (templateName && fileExists(templatePath)) {
87
79
  //read the target file content
88
80
  data = fs.readJsonSync(targetPath);
89
-
90
81
  //override externalJS settings with those of the local template file
91
- let templateData = fs.readJsonSync(templatePath);
82
+ const templateData = fs.readJsonSync(templatePath);
92
83
  for (const objKey of Object.keys(templateData)) {
93
84
  data[objKey] = templateData[objKey];
94
85
  }
95
-
96
86
  // write out the target file content
97
87
  fs.writeJsonSync(targetPath, data);
98
88
  }
99
89
  }
100
-
101
90
  /**
102
91
  * Checks if the specified file exists
103
- *
104
- * @param {string} file - path to the file
92
+ *
93
+ * @param {string} file - path to the file
105
94
  */
106
95
  function fileExists(file) {
107
96
  try {
108
97
  fs.accessSync(file);
109
- } catch (e) {
98
+ }
99
+ catch (e) {
110
100
  return false;
111
101
  }
112
102
  return true;
113
103
  }
114
-
115
104
  /**
116
105
  * Copies the visual template directory
117
- *
106
+ *
118
107
  * @param {string} targetPath - file path to root of visual package
119
108
  * @param {string} templateName - template to use for generating the visual
120
109
  */
@@ -122,54 +111,50 @@ function copyVisualTemplate(targetPath, templateName) {
122
111
  fs.copySync(path.join(VISUAL_TEMPLATES_PATH, '_global'), targetPath);
123
112
  fs.copySync(path.join(VISUAL_TEMPLATES_PATH, templateName), targetPath);
124
113
  }
125
-
126
114
  /**
127
115
  * Checks if the specified template is valid
128
- *
116
+ *
129
117
  * @param {string} templateName - template to use for generating the visual
130
118
  */
131
119
  function validTemplate(templateName) {
132
120
  try {
133
121
  fs.accessSync(path.join(VISUAL_TEMPLATES_PATH, templateName));
134
- } catch (e) {
122
+ }
123
+ catch (e) {
135
124
  return false;
136
125
  }
137
126
  return true;
138
127
  }
139
-
140
128
  const defaultOptions = {
141
129
  force: false,
142
130
  template: 'default',
143
131
  apiVersion: API_VERSION,
144
132
  externalJS: []
145
133
  };
146
-
147
- class VisualGenerator {
134
+ export default class VisualGenerator {
148
135
  /**
149
136
  * Generates a new visual
150
- *
137
+ *
151
138
  * @param {string} targetPath - file path for creation of the new visual package
152
139
  * @param {string} visualName - name of the new visual package
153
140
  * @param {object} options - specify options for the visual generator
154
- * @returns {Promise<string>} - promise resolves with the path to the newly created package
141
+ * @returns {Promise<string>} - promise resolves with the path to the newly created package
155
142
  */
156
- static generate(targetPath, visualName, options) {
143
+ static generateVisual(targetPath, visualName, options) {
157
144
  return new Promise((resolve, reject) => {
158
- let buildOptions = lodashDefaults(options, defaultOptions);
159
- if (!buildOptions.apiVersion || compareVersions.compare(buildOptions.apiVersion, minAPIversion, "<")) {
145
+ const buildOptions = lodashDefaults(options, defaultOptions);
146
+ if (!buildOptions.apiVersion || compareVersions(buildOptions.apiVersion, minAPIversion) === -1) {
160
147
  return reject(new Error(`Can not generate a visual with an API below than ${minAPIversion}, current API is '${buildOptions.apiVersion}'.`));
161
148
  }
162
- let visualOptions = generateVisualOptions(visualName, buildOptions.apiVersion);
149
+ const visualOptions = generateVisualOptions(visualName, buildOptions.apiVersion);
163
150
  const validationResult = VisualGenerator.checkVisualName(visualOptions.name);
164
151
  if (!visualOptions || !visualOptions.name || validationResult) {
165
152
  return reject(new Error(validationResult || "Invalid visual name"));
166
153
  }
167
-
168
154
  if (!validTemplate(buildOptions.template)) {
169
- return reject(new Error('Invalid template'));
155
+ return reject(new Error(`Invalid template "${buildOptions.template}"`));
170
156
  }
171
-
172
- let visualPath = path.join(targetPath, visualOptions.name);
157
+ const visualPath = path.join(targetPath, visualOptions.name);
173
158
  fs.access(visualPath, err => {
174
159
  if (!err && !buildOptions.force) {
175
160
  return reject(new Error('This visual already exists. Use force to overwrite.'));
@@ -181,28 +166,27 @@ class VisualGenerator {
181
166
  copyVisualTemplate(visualPath, buildOptions.template);
182
167
  createPbiVizJson(visualPath, visualOptions, options.template);
183
168
  resolve(visualPath);
184
- } catch (e) {
169
+ }
170
+ catch (e) {
185
171
  reject(e);
186
172
  }
187
173
  });
188
174
  });
189
175
  }
190
-
191
176
  /**
192
177
  * Generates a random GUID for your visual
193
178
  */
194
179
  static generateVisualGuid() {
195
- return uuid.v4().replace(/-/g, '').toUpperCase();
180
+ return crypto.randomUUID().replace(/-/g, '').toUpperCase();
196
181
  }
197
-
198
182
  /**
199
- * Check visual name
183
+ * Check visual name
200
184
  * Using https://github.com/mathiasbynens/mothereff.in/tree/master/js-properties
201
- *
185
+ *
202
186
  * @static
203
187
  * @param {string} name Visual name
204
188
  * @returns {string} error message
205
- *
189
+ *
206
190
  * @memberof VisualGenerator
207
191
  */
208
192
  static checkVisualName(name) {
@@ -222,14 +206,16 @@ class VisualGenerator {
222
206
  });
223
207
  if (regexNumber.test(name)) {
224
208
  return `The visual name can't begin with a number digit`;
225
- } else if (!regexpWrongSymbols.test(name)) {
209
+ }
210
+ else if (!regexpWrongSymbols.test(name)) {
226
211
  return `The visual name can contain only letters and numbers`;
227
- } else if (regexES3ReservedWord.test(valueAsUnescapedString)) {
212
+ }
213
+ else if (regexES3ReservedWord.test(valueAsUnescapedString)) {
228
214
  return `The visual name cannot be equal to a reserved JavaScript keyword.
229
215
  More information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords`;
230
- } else if (regexZeroWidth.test(valueAsUnescapedString)) {
216
+ }
217
+ else if (regexZeroWidth.test(valueAsUnescapedString)) {
231
218
  return `The visual name can't be empty`;
232
219
  }
233
220
  }
234
221
  }
235
- module.exports = VisualGenerator;