powerbi-visuals-tools 5.6.0 → 6.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.
package/Changelog.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  This page contains information about changes to the PowerBI Visual Tools (pbiviz).
4
4
 
5
+ ## 6.0.0
6
+ * **Introduced pbiviz.js support.** This feature allows generate configuration dynamically using benefits of JavaScript.
7
+ It allows you to easily use any js logic to build your pbiviz file using environment variables or other parameters.
8
+ * Updated dependencies to the latest versions.
9
+
5
10
  ## 5.6.0
6
11
  * Updated to ESLint v9
7
12
  * Updated to TypeScript v5
package/bin/pbiviz.js CHANGED
@@ -32,7 +32,7 @@ import CommandManager from '../lib/CommandManager.js';
32
32
  import { readJsonFromRoot } from '../lib/utils.js';
33
33
  import { program, Option } from 'commander';
34
34
 
35
- const npmPackage = readJsonFromRoot('package.json');
35
+ const npmPackage = await readJsonFromRoot('package.json');
36
36
  const rootPath = process.cwd();
37
37
  const pbivizFile = 'pbiviz.json';
38
38
 
@@ -84,7 +84,7 @@ pbiviz
84
84
  .option('--no-stats', "Doesn't generate statistics files")
85
85
  .option('--skip-api', "Skips powerbi-visuals-api verifying")
86
86
  .option('-l, --all-locales', "Keeps all locale files in the package. By default only used inside stringResources folder locales are included.")
87
- .option('-f, --pbiviz-file <pbiviz-file>', "Path to pbiviz.json file (useful for debugging)", pbivizFile)
87
+ .option('-f, --pbiviz-file <pbiviz-file>', "Path to visual config file (pbiviz.json / pbiviz.mjs)", pbivizFile)
88
88
  .action(async (options) => {
89
89
  CommandManager.start(options, rootPath);
90
90
  });
@@ -100,7 +100,7 @@ pbiviz
100
100
  .option('-l, --all-locales', "Keeps all locale files in the package. By default only used inside stringResources folder locales are included.")
101
101
  .option('-v, --verbose', "Enables verbose logging")
102
102
  .option('--fix', 'Enable autofixing of lint errors')
103
- .option('-p, --pbiviz-file <pbiviz-file>', "Path to pbiviz.json file (useful for debugging)", pbivizFile)
103
+ .option('-p, --pbiviz-file <pbiviz-file>', "Path to visual config file (pbiviz.json / pbiviz.mjs)", pbivizFile)
104
104
  .addOption(new Option('-c, --compression <compressionLevel>', "Enables compression of visual package")
105
105
  .choices(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])
106
106
  .default('6')
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-case-declarations */
2
1
  /*
3
2
  * Power BI Visual CLI
4
3
  *
@@ -33,7 +32,7 @@ import crypto from "crypto";
33
32
  import { readJsonFromRoot } from './utils.js';
34
33
  import ConsoleWriter from './ConsoleWriter.js';
35
34
  const certSafePeriod = 1000 * 60 * 60 * 24; // 24 hours
36
- const config = readJsonFromRoot('config.json');
35
+ const config = await readJsonFromRoot('config.json');
37
36
  const pathToCertFolder = path.join(os.homedir(), config.server.certificateFolder);
38
37
  const secretFilesPath = {
39
38
  certPath: path.join(pathToCertFolder, config.server.certificate),
@@ -17,17 +17,15 @@ export default class CommandManager {
17
17
  pbivizFile: options.pbivizFile,
18
18
  };
19
19
  const visualManager = new VisualManager(rootPath);
20
- await visualManager
21
- .prepareVisual(options.pbivizFile)
22
- .validateVisual()
23
- .initializeWebpack(webpackOptions);
20
+ await visualManager.prepareVisual(options.pbivizFile);
21
+ await visualManager.validateVisual();
22
+ await visualManager.initializeWebpack(webpackOptions);
24
23
  visualManager.startWebpackServer(options.drop);
25
24
  }
26
25
  static async lint(options, rootPath) {
27
26
  const visualManager = new VisualManager(rootPath);
28
- await visualManager
29
- .prepareVisual()
30
- .runLintValidation(options);
27
+ await visualManager.prepareVisual();
28
+ await visualManager.runLintValidation(options);
31
29
  }
32
30
  static async package(options, rootPath) {
33
31
  if (!options.pbiviz && !options.resources) {
@@ -50,11 +48,12 @@ export default class CommandManager {
50
48
  verbose: options.verbose,
51
49
  fix: options.fix,
52
50
  };
53
- const visual = new VisualManager(rootPath).prepareVisual(options.pbivizFile);
51
+ const visualManager = new VisualManager(rootPath);
52
+ const visual = await visualManager.prepareVisual(options.pbivizFile);
54
53
  await visual.runLintValidation(lintOptions);
55
- visual.validateVisual(options.verbose)
56
- .initializeWebpack(webpackOptions)
57
- .then(visualManager => visualManager.generatePackage(options.verbose));
54
+ await visual.validateVisual(options.verbose);
55
+ await visual.initializeWebpack(webpackOptions)
56
+ .then(manager => manager.generatePackage(options.verbose));
58
57
  }
59
58
  static new({ force, template }, name, rootPath) {
60
59
  const generateOptions = {
@@ -63,10 +62,10 @@ export default class CommandManager {
63
62
  };
64
63
  VisualManager.createVisual(rootPath, name, generateOptions);
65
64
  }
66
- static info(rootPath) {
67
- new VisualManager(rootPath)
68
- .prepareVisual()
69
- .displayInfo();
65
+ static async info(rootPath) {
66
+ const visualManager = new VisualManager(rootPath);
67
+ await visualManager.prepareVisual();
68
+ await visualManager.displayInfo();
70
69
  }
71
70
  static async installCert() {
72
71
  await createCertificate();
@@ -5,7 +5,7 @@ import VisualGenerator from "./VisualGenerator.js";
5
5
  import { exec } from 'child_process';
6
6
  import fs from 'fs-extra';
7
7
  import path from 'path';
8
- const config = readJsonFromRoot('config.json');
8
+ const config = await readJsonFromRoot('config.json');
9
9
  export default class TemplateFetcher {
10
10
  templateName;
11
11
  visualName;
@@ -31,7 +31,7 @@ import fs from 'fs-extra';
31
31
  import lodashDefaults from 'lodash.defaults';
32
32
  import path from 'path';
33
33
  import template from '../templates/pbiviz-json-template.js';
34
- const config = readJsonFromRoot('config.json');
34
+ const config = await readJsonFromRoot('config.json');
35
35
  const VISUAL_TEMPLATES_PATH = path.join(getRootPath(), config.templates.visuals);
36
36
  const API_VERSION = config.generate.apiVersion;
37
37
  const minAPIversion = config.constants.minAPIversion;
@@ -39,7 +39,7 @@ import { FeatureManager, Status } from "./FeatureManager.js";
39
39
  import { Severity, Stage } from "./features/FeatureTypes.js";
40
40
  import TemplateFetcher from "./TemplateFetcher.js";
41
41
  import { LintValidator } from "./LintValidator.js";
42
- const globalConfig = readJsonFromRoot('config.json');
42
+ const globalConfig = await readJsonFromRoot('config.json');
43
43
  const PBIVIZ_FILE = 'pbiviz.json';
44
44
  /**
45
45
  * Represents an instance of a visual package based on file path
@@ -57,10 +57,10 @@ export default class VisualManager {
57
57
  constructor(rootPath) {
58
58
  this.basePath = rootPath;
59
59
  }
60
- prepareVisual(pbivizFile = PBIVIZ_FILE) {
61
- if (this.doesPBIVIZExists(pbivizFile)) {
62
- this.pbivizConfig = readJsonFromVisual(pbivizFile, this.basePath);
63
- this.createVisualInstance();
60
+ async prepareVisual(pbivizFile = PBIVIZ_FILE) {
61
+ this.pbivizConfig = await readJsonFromVisual(pbivizFile, this.basePath);
62
+ if (this.pbivizConfig) {
63
+ await this.createVisualInstance();
64
64
  }
65
65
  else {
66
66
  ConsoleWriter.error(pbivizFile + ' not found. You must be in the root of a visual project to run this command.');
@@ -80,8 +80,8 @@ export default class VisualManager {
80
80
  }
81
81
  }
82
82
  }
83
- createVisualInstance() {
84
- this.capabilities = readJsonFromVisual("capabilities.json", this.basePath);
83
+ async createVisualInstance() {
84
+ this.capabilities = await readJsonFromVisual("capabilities.json", this.basePath);
85
85
  this.visual = new Visual(this.capabilities, this.pbivizConfig);
86
86
  }
87
87
  async initializeWebpack(webpackOptions) {
@@ -188,7 +188,7 @@ export default class VisualManager {
188
188
  ConsoleWriter.warning('Running with force flag. Existing files will be overwritten');
189
189
  }
190
190
  try {
191
- const config = readJsonFromRoot('config.json');
191
+ const config = await readJsonFromRoot('config.json');
192
192
  if (config.visualTemplates[generateOptions.template]) {
193
193
  new TemplateFetcher(generateOptions.template, visualName, undefined)
194
194
  .fetch();
@@ -13,8 +13,8 @@ import { PowerBICustomVisualsWebpackPlugin, LocalizationLoader } from 'powerbi-v
13
13
  import ConsoleWriter from './ConsoleWriter.js';
14
14
  import { resolveCertificate } from "./CertificateTools.js";
15
15
  import { readJsonFromRoot, readJsonFromVisual } from './utils.js';
16
- const config = readJsonFromRoot('config.json');
17
- const npmPackage = readJsonFromRoot('package.json');
16
+ const config = await readJsonFromRoot('config.json');
17
+ const npmPackage = await readJsonFromRoot('package.json');
18
18
  const visualPlugin = "visualPlugin.ts";
19
19
  const encoding = "utf8";
20
20
  export default class WebPackWrap {
@@ -123,7 +123,7 @@ export default class WebPackWrap {
123
123
  await this.configureAPIVersion();
124
124
  }
125
125
  const api = await WebPackWrap.loadAPIPackage();
126
- const dependenciesPath = this.pbiviz.dependencies && path.join(process.cwd(), this.pbiviz.dependencies);
126
+ const dependenciesPath = typeof this.pbiviz.dependencies === "string" && path.join(process.cwd(), this.pbiviz.dependencies);
127
127
  let pluginConfiguration = {
128
128
  ...lodashCloneDeep(visualPackage.pbivizConfig),
129
129
  apiVersion: api.version,
@@ -250,8 +250,8 @@ export default class WebPackWrap {
250
250
  allLocales: false,
251
251
  pbivizFile: 'pbiviz.json',
252
252
  }) {
253
- const tsconfig = readJsonFromVisual('tsconfig.json');
254
- this.pbiviz = readJsonFromVisual(options.pbivizFile);
253
+ const tsconfig = await readJsonFromVisual('tsconfig.json');
254
+ this.pbiviz = await readJsonFromVisual(options.pbivizFile);
255
255
  const capabilitiesPath = this.pbiviz.capabilities;
256
256
  visualPackage.pbivizConfig.capabilities = capabilitiesPath;
257
257
  const dependenciesPath = this.pbiviz.dependencies && path.join(process.cwd(), this.pbiviz.dependencies);
@@ -7,8 +7,8 @@ export default class APIVersion {
7
7
  static visualFeatureType = VisualFeatureType.NonSlicer;
8
8
  static minAPIversion;
9
9
  static errorMessage;
10
- static isSupported(visual) {
11
- const globalConfig = readJsonFromRoot('config.json');
10
+ static async isSupported(visual) {
11
+ const globalConfig = await readJsonFromRoot('config.json');
12
12
  this.minAPIversion = globalConfig.constants.minAPIversion;
13
13
  this.errorMessage = `API version must be at least ${this.minAPIversion}.`;
14
14
  return visual.doesAPIVersionMatch(this.minAPIversion);
package/lib/utils.js CHANGED
@@ -22,12 +22,22 @@ export function getRootPath() {
22
22
  const pathToDirectory = fileURLToPath(import.meta.url);
23
23
  return path.join(pathToDirectory, "..", "..");
24
24
  }
25
- function readFileFromRoot(filePath) {
26
- return fs.readFileSync(path.join(getRootPath(), filePath), "utf8");
25
+ export function getJsPath(filePath) {
26
+ return filePath.replace(/\.json$/, '.mjs');
27
27
  }
28
- export function readJsonFromRoot(filePath) {
29
- return JSON.parse(readFileFromRoot(filePath));
28
+ async function safelyImport(filePath) {
29
+ return fs.existsSync(filePath) && (await import(`file://${filePath}`)).default;
30
30
  }
31
- export function readJsonFromVisual(filePath, visualPath) {
32
- return JSON.parse(fs.readFileSync(path.join(visualPath ?? process.cwd(), filePath), "utf8"));
31
+ function safelyParse(filePath) {
32
+ return fs.existsSync(filePath) && JSON.parse(fs.readFileSync(filePath, "utf-8"));
33
+ }
34
+ export async function readJsonFromRoot(jsonFilename) {
35
+ const jsonPath = path.join(getRootPath(), jsonFilename);
36
+ const jsPath = getJsPath(jsonPath);
37
+ return (await safelyImport(jsPath)) || safelyParse(jsonPath);
38
+ }
39
+ export async function readJsonFromVisual(filePath, visualPath) {
40
+ const jsonPath = path.join(visualPath ?? process.cwd(), filePath);
41
+ const jsPath = getJsPath(jsonPath);
42
+ return (await safelyImport(jsPath)) || safelyParse(jsonPath);
33
43
  }
@@ -3,7 +3,7 @@ import MiniCssExtractPlugin from "mini-css-extract-plugin";
3
3
  import TerserPlugin from "terser-webpack-plugin";
4
4
  import path from "path";
5
5
  import webpack from "webpack";
6
- const config = readJsonFromRoot("/config.json");
6
+ const config = await readJsonFromRoot("/config.json");
7
7
  const rootPath = getRootPath();
8
8
  const webpackConfig = {
9
9
  entry: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "powerbi-visuals-tools",
3
- "version": "5.6.0",
3
+ "version": "6.0.0",
4
4
  "description": "Command line tool for creating and publishing visuals for Power BI",
5
5
  "main": "./bin/pbiviz.js",
6
6
  "type": "module",
@@ -8,12 +8,11 @@
8
8
  "build": "tsc",
9
9
  "pbiviz": "node ./bin/pbiviz.js",
10
10
  "start": "npm run pbiviz start",
11
- "test": "npm run build && npm run clean-tests && npm run lint && npm run jasmine",
11
+ "test": "npm run build && npm run lint && npm run jasmine",
12
12
  "jasmine": "node spec/jasmine-runner.js",
13
13
  "jasmine-inspect": "node --inspect spec/jasmine-runner.js",
14
14
  "lint": "npx eslint .",
15
- "clean-tests": "node spec/clean-tests.js",
16
- "debug-tests": "npm run clean-tests && npm run lint && npm run jasmine-inspect"
15
+ "debug-tests": "npm run lint && npm run jasmine-inspect"
17
16
  },
18
17
  "bin": {
19
18
  "pbiviz": "./bin/pbiviz.js"
@@ -29,33 +28,33 @@
29
28
  },
30
29
  "homepage": "https://github.com/Microsoft/PowerBI-visuals-tools#readme",
31
30
  "dependencies": {
32
- "@typescript-eslint/parser": "^8.8.0",
31
+ "@typescript-eslint/parser": "^8.26.0",
33
32
  "assert": "^2.1.0",
34
33
  "async": "^3.2.6",
35
34
  "browserify-zlib": "^0.2.0",
36
35
  "buffer": "^6.0.3",
37
- "chalk": "^5.3.0",
38
- "commander": "^12.1.0",
36
+ "chalk": "^5.4.1",
37
+ "commander": "^13.1.0",
39
38
  "compare-versions": "^6.1.1",
40
39
  "console-browserify": "^1.2.0",
41
40
  "constants-browserify": "^1.0.0",
42
- "crypto-browserify": "^3.12.0",
41
+ "crypto-browserify": "^3.12.1",
43
42
  "css-loader": "^7.1.2",
44
43
  "domain-browser": "^5.7.0",
45
44
  "events": "^3.3.0",
46
45
  "extra-watch-webpack-plugin": "^1.0.3",
47
- "fs-extra": "^11.2.0",
46
+ "fs-extra": "^11.3.0",
48
47
  "https-browserify": "^1.0.0",
49
48
  "inline-source-map": "^0.6.3",
50
49
  "json-loader": "0.5.7",
51
50
  "jszip": "^3.10.1",
52
- "less": "^4.2.0",
51
+ "less": "^4.2.2",
53
52
  "less-loader": "^12.2.0",
54
53
  "lodash.clonedeep": "4.5.0",
55
54
  "lodash.defaults": "4.2.0",
56
55
  "lodash.isequal": "4.5.0",
57
56
  "lodash.ismatch": "^4.4.0",
58
- "mini-css-extract-plugin": "^2.9.1",
57
+ "mini-css-extract-plugin": "^2.9.2",
59
58
  "os-browserify": "^0.3.0",
60
59
  "path-browserify": "^1.0.1",
61
60
  "powerbi-visuals-webpack-plugin": "4.1.0",
@@ -63,30 +62,30 @@
63
62
  "process": "^0.11.10",
64
63
  "punycode": "^2.3.1",
65
64
  "querystring-es3": "^0.2.1",
66
- "readable-stream": "^4.5.2",
65
+ "readable-stream": "^4.7.0",
67
66
  "stream-browserify": "^3.0.0",
68
67
  "stream-http": "^3.2.0",
69
68
  "string_decoder": "^1.3.0",
70
- "terser-webpack-plugin": "^5.3.10",
69
+ "terser-webpack-plugin": "^5.3.14",
71
70
  "timers-browserify": "^2.0.12",
72
- "ts-loader": "^9.5.1",
71
+ "ts-loader": "^9.5.2",
73
72
  "tty-browserify": "^0.0.1",
74
- "typescript": "^5.5.0",
73
+ "typescript": "^5.8.2",
75
74
  "url": "^0.11.4",
76
75
  "util": "^0.12.5",
77
76
  "vm-browserify": "^1.1.2",
78
- "webpack": "^5.95.0",
77
+ "webpack": "^5.98.0",
79
78
  "webpack-bundle-analyzer": "4.10.2",
80
- "webpack-dev-server": "^5.1.0"
79
+ "webpack-dev-server": "^5.2.0"
81
80
  },
82
81
  "devDependencies": {
83
- "@typescript-eslint/eslint-plugin": "^8.8.0",
84
- "eslint": "^9.11.1",
85
- "jasmine": "5.3.0",
82
+ "@typescript-eslint/eslint-plugin": "^8.26.0",
83
+ "eslint": "^9.22.0",
84
+ "jasmine": "5.3.1",
86
85
  "jasmine-spec-reporter": "7.0.0",
87
- "semver": "7.6.3",
86
+ "semver": "7.7.1",
88
87
  "tree-kill": "1.2.2",
89
- "webpack-cli": "^5.1.4"
88
+ "webpack-cli": "^6.0.1"
90
89
  },
91
90
  "optionalDependencies": {
92
91
  "fsevents": "*"