powerbi-visuals-tools 6.1.3 → 7.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/.eslintrc.json +21 -0
- package/CVClientLA.md +85 -0
- package/Changelog.md +9 -0
- package/package.json +11 -35
- package/certs/blank +0 -0
- package/lib/CertificateTools.js +0 -262
- package/lib/CommandManager.js +0 -75
- package/lib/ConsoleWriter.js +0 -188
- package/lib/FeatureManager.js +0 -43
- package/lib/LintValidator.js +0 -61
- package/lib/Package.js +0 -46
- package/lib/TemplateFetcher.js +0 -111
- package/lib/Visual.js +0 -29
- package/lib/VisualGenerator.js +0 -221
- package/lib/VisualManager.js +0 -316
- package/lib/WebPackWrap.js +0 -268
- package/lib/features/APIVersion.js +0 -16
- package/lib/features/AdvancedEditMode.js +0 -12
- package/lib/features/AllowInteractions.js +0 -12
- package/lib/features/AnalyticsPane.js +0 -17
- package/lib/features/BaseFeature.js +0 -9
- package/lib/features/Bookmarks.js +0 -12
- package/lib/features/ColorPalette.js +0 -12
- package/lib/features/ConditionalFormatting.js +0 -12
- package/lib/features/ContextMenu.js +0 -12
- package/lib/features/DrillDown.js +0 -16
- package/lib/features/FeatureTypes.js +0 -23
- package/lib/features/FetchMoreData.js +0 -22
- package/lib/features/FileDownload.js +0 -12
- package/lib/features/FormatPane.js +0 -12
- package/lib/features/HighContrast.js +0 -12
- package/lib/features/HighlightData.js +0 -12
- package/lib/features/KeyboardNavigation.js +0 -12
- package/lib/features/LandingPage.js +0 -12
- package/lib/features/LaunchURL.js +0 -12
- package/lib/features/LocalStorage.js +0 -12
- package/lib/features/Localizations.js +0 -12
- package/lib/features/ModalDialog.js +0 -12
- package/lib/features/RenderingEvents.js +0 -13
- package/lib/features/SelectionAcrossVisuals.js +0 -12
- package/lib/features/SyncSlicer.js +0 -12
- package/lib/features/Tooltips.js +0 -12
- package/lib/features/TotalSubTotal.js +0 -12
- package/lib/features/VisualVersion.js +0 -12
- package/lib/features/WarningIcon.js +0 -12
- package/lib/features/index.js +0 -28
- package/lib/utils.js +0 -43
- package/lib/webpack.config.js +0 -148
package/lib/ConsoleWriter.js
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Power BI Visual CLI
|
|
3
|
-
*
|
|
4
|
-
* Copyright (c) Microsoft Corporation
|
|
5
|
-
* All rights reserved.
|
|
6
|
-
* MIT License
|
|
7
|
-
*
|
|
8
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
-
* of this software and associated documentation files (the ""Software""), to deal
|
|
10
|
-
* in the Software without restriction, including without limitation the rights
|
|
11
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
13
|
-
* furnished to do so, subject to the following conditions:
|
|
14
|
-
*
|
|
15
|
-
* The above copyright notice and this permission notice shall be included in
|
|
16
|
-
* all copies or substantial portions of the Software.
|
|
17
|
-
*
|
|
18
|
-
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
24
|
-
* THE SOFTWARE.
|
|
25
|
-
*/
|
|
26
|
-
"use strict";
|
|
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;
|
|
33
|
-
function prependLogTag(tag, args) {
|
|
34
|
-
return [tag].concat(args);
|
|
35
|
-
}
|
|
36
|
-
export default class ConsoleWriter {
|
|
37
|
-
/** Causes the terminal to beep */
|
|
38
|
-
static beep() {
|
|
39
|
-
process.stdout.write("\x07");
|
|
40
|
-
}
|
|
41
|
-
/** Outputs a blank line */
|
|
42
|
-
static blank() {
|
|
43
|
-
console.info(preferredChalk.reset(' '));
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Outputs arguments with the "done" tag / colors
|
|
47
|
-
*
|
|
48
|
-
* @param {array} arguments - arguments passed through to console.info
|
|
49
|
-
*/
|
|
50
|
-
static done(args) {
|
|
51
|
-
const tag = preferredChalk.bgGreen(' done ');
|
|
52
|
-
console.info.apply(this, prependLogTag(tag, args));
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Outputs arguments with the "info" tag / colors
|
|
56
|
-
*
|
|
57
|
-
* @param {array} args - arguments passed through to console.info
|
|
58
|
-
*/
|
|
59
|
-
static info(args) {
|
|
60
|
-
const tag = preferredChalk.bgCyan(' info ');
|
|
61
|
-
console.info.apply(this, prependLogTag(tag, args));
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Outputs arguments with the "warn" tag / colors
|
|
65
|
-
*
|
|
66
|
-
* @param {array} args - arguments passed through to console.warn
|
|
67
|
-
*/
|
|
68
|
-
static warning(args) {
|
|
69
|
-
const tag = preferredChalk.bgYellow.black(' warn ');
|
|
70
|
-
console.warn.apply(this, prependLogTag(tag, args));
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Outputs arguments with the "error" tag / colors
|
|
74
|
-
*
|
|
75
|
-
* @param {array} args - arguments passed through to console.error
|
|
76
|
-
*/
|
|
77
|
-
static error(args) {
|
|
78
|
-
const tag = preferredChalk.bgRed(' error ');
|
|
79
|
-
console.error.apply(this, prependLogTag(tag, args));
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Outputs an object as a table
|
|
83
|
-
*
|
|
84
|
-
* @param {string} data - object to output
|
|
85
|
-
* @param {number} [depthLimit=Infinity] - limit the number of levels to recurse
|
|
86
|
-
* @param {string} [keyPrefix=''] - text to prepend to each key
|
|
87
|
-
*/
|
|
88
|
-
static infoTable(data, depthLimit, keyPrefix) {
|
|
89
|
-
if (!data) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
const limit = typeof depthLimit === 'undefined' ? Infinity : depthLimit;
|
|
93
|
-
for (const key in data) {
|
|
94
|
-
const item = data[key];
|
|
95
|
-
const itemKey = (keyPrefix || '') + key;
|
|
96
|
-
if (limit > 1 && typeof item === 'object' && !Array.isArray(item)) {
|
|
97
|
-
ConsoleWriter.infoTable(item, limit - 1, itemKey + '.');
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
ConsoleWriter.infoTableRow(itemKey, item);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Outputs a table row with even spaced keys
|
|
106
|
-
*
|
|
107
|
-
* @param {string} key - title of this row
|
|
108
|
-
* @param {string} value - value for this row
|
|
109
|
-
* @param {number} [keyWidth=30] - width used for padding of the key column
|
|
110
|
-
*/
|
|
111
|
-
static infoTableRow(key, value, keyWidth) {
|
|
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]);
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Outputs formatted errors
|
|
119
|
-
*
|
|
120
|
-
* @param {Array<Error>} errors
|
|
121
|
-
*/
|
|
122
|
-
static formattedErrors(errors) {
|
|
123
|
-
if (errors && Array.isArray(errors)) {
|
|
124
|
-
errors.forEach((error) => {
|
|
125
|
-
if (!error) {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
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}`]);
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
ConsoleWriter.error(['UNKNOWN', errors]);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Outputs ascii art of the PowerBI logo
|
|
141
|
-
*/
|
|
142
|
-
static getLogoVisualization() {
|
|
143
|
-
return fs.readFileSync(path.join(getRootPath(), 'assets', 'logo.txt')).toString();
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Outputs validation log from PBIVIZ package checking
|
|
147
|
-
*/
|
|
148
|
-
static validationLog(log) {
|
|
149
|
-
// api/js/css/pkg
|
|
150
|
-
const filterChecks = (attrCB, propCB) => {
|
|
151
|
-
for (const checkname in log) {
|
|
152
|
-
if (checkname !== 'valid') {
|
|
153
|
-
const checkpoint = log[checkname];
|
|
154
|
-
ConsoleWriter[checkpoint.error.length ? 'info' : 'done'](checkpoint.check);
|
|
155
|
-
attrCB(checkpoint, propCB);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
// error/message/ok
|
|
160
|
-
const filterCheckAttrs = (checkpoint, propCB) => {
|
|
161
|
-
for (const propName in checkpoint) {
|
|
162
|
-
if (propName !== 'message') {
|
|
163
|
-
const prop = checkpoint[propName];
|
|
164
|
-
if (typeof (prop) === 'object' && prop.length) {
|
|
165
|
-
propCB(prop, propName);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
// col/line/text
|
|
171
|
-
const filterAttrProps = (props, propName) => {
|
|
172
|
-
props.forEach((opt) => {
|
|
173
|
-
const result = [];
|
|
174
|
-
for (const key in opt) {
|
|
175
|
-
result.push(opt[key]);
|
|
176
|
-
}
|
|
177
|
-
if (result.length) {
|
|
178
|
-
ConsoleWriter[propName === 'error' ? 'error' : 'warn'](result.join(' --> '));
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
};
|
|
182
|
-
filterChecks(filterCheckAttrs, filterAttrProps);
|
|
183
|
-
const type = log.valid ? 'done' : 'error';
|
|
184
|
-
const text = log.valid ? 'Valid package' : 'Invalid package';
|
|
185
|
-
ConsoleWriter.blank();
|
|
186
|
-
ConsoleWriter[type](text);
|
|
187
|
-
}
|
|
188
|
-
}
|
package/lib/FeatureManager.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { Severity } from "./features/FeatureTypes.js";
|
|
2
|
-
import * as features from "./features/index.js";
|
|
3
|
-
export var Status;
|
|
4
|
-
(function (Status) {
|
|
5
|
-
Status[Status["Success"] = 0] = "Success";
|
|
6
|
-
Status[Status["Error"] = 1] = "Error";
|
|
7
|
-
})(Status || (Status = {}));
|
|
8
|
-
export class FeatureManager {
|
|
9
|
-
features = Object.keys(features).map(key => features[key]);
|
|
10
|
-
validate(stage, sourceInstance) {
|
|
11
|
-
const result = {
|
|
12
|
-
status: Status.Success,
|
|
13
|
-
logs: {
|
|
14
|
-
errors: [],
|
|
15
|
-
warnings: [],
|
|
16
|
-
info: [],
|
|
17
|
-
deprecation: []
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
this.features
|
|
21
|
-
.filter(feature => feature.stage == stage)
|
|
22
|
-
.filter(feature => feature.visualFeatureType & sourceInstance.visualFeatureType)
|
|
23
|
-
.filter(feature => !feature.isSupported(sourceInstance))
|
|
24
|
-
.forEach(({ errorMessage, severity }) => {
|
|
25
|
-
switch (severity) {
|
|
26
|
-
case Severity.Error:
|
|
27
|
-
result.status = Status.Error;
|
|
28
|
-
result.logs.errors.push(errorMessage);
|
|
29
|
-
break;
|
|
30
|
-
case Severity.Warning:
|
|
31
|
-
result.logs.warnings.push(errorMessage);
|
|
32
|
-
break;
|
|
33
|
-
case Severity.Info:
|
|
34
|
-
result.logs.info.push(errorMessage);
|
|
35
|
-
break;
|
|
36
|
-
case Severity.Deprecation:
|
|
37
|
-
result.logs.deprecation.push(errorMessage);
|
|
38
|
-
break;
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
return result;
|
|
42
|
-
}
|
|
43
|
-
}
|
package/lib/LintValidator.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { ESLint } from "eslint";
|
|
2
|
-
import powerbiPlugin from 'eslint-plugin-powerbi-visuals';
|
|
3
|
-
import ConsoleWriter from "./ConsoleWriter.js";
|
|
4
|
-
import { getRootPath } from "./utils.js";
|
|
5
|
-
export class LintValidator {
|
|
6
|
-
visualPath;
|
|
7
|
-
rootPath;
|
|
8
|
-
isVerboseMode;
|
|
9
|
-
shouldFix;
|
|
10
|
-
config;
|
|
11
|
-
linterInstance;
|
|
12
|
-
constructor({ verbose, fix }) {
|
|
13
|
-
this.visualPath = process.cwd();
|
|
14
|
-
this.rootPath = getRootPath();
|
|
15
|
-
this.isVerboseMode = verbose;
|
|
16
|
-
this.shouldFix = fix;
|
|
17
|
-
this.prepareConfig();
|
|
18
|
-
this.linterInstance = new ESLint(this.config);
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Runs lint validation in the visual folder
|
|
22
|
-
*/
|
|
23
|
-
async runLintValidation() {
|
|
24
|
-
ConsoleWriter.info("Running lint check...");
|
|
25
|
-
// By default it will lint all files in the src of current working directory
|
|
26
|
-
const results = await this.linterInstance.lintFiles("src/");
|
|
27
|
-
if (this.shouldFix) {
|
|
28
|
-
await this.fixErrors(results);
|
|
29
|
-
}
|
|
30
|
-
await this.outputResults(results);
|
|
31
|
-
ConsoleWriter.info("Lint check completed.");
|
|
32
|
-
}
|
|
33
|
-
async fixErrors(results) {
|
|
34
|
-
ConsoleWriter.info("Lint fixing errors...");
|
|
35
|
-
await ESLint.outputFixes(results);
|
|
36
|
-
}
|
|
37
|
-
async outputResults(results) {
|
|
38
|
-
if (this.isVerboseMode) {
|
|
39
|
-
const formatter = await this.linterInstance.loadFormatter("stylish");
|
|
40
|
-
const formattedResults = await formatter.format(results);
|
|
41
|
-
console.log(formattedResults);
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
const filteredResults = ESLint.getErrorResults(results);
|
|
45
|
-
// get total amount of errors and warnings in all elements of filteredResults
|
|
46
|
-
const totalErrors = filteredResults.reduce((acc, curr) => acc + curr.errorCount, 0);
|
|
47
|
-
const totalWarnings = filteredResults.reduce((acc, curr) => acc + curr.warningCount, 0);
|
|
48
|
-
if (totalErrors > 0 || totalWarnings > 0) {
|
|
49
|
-
ConsoleWriter.error(`Linter found ${totalErrors} errors and ${totalWarnings} warnings. Run with --verbose flag to see details.`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
prepareConfig() {
|
|
54
|
-
ConsoleWriter.warning("Using recommended eslint config.");
|
|
55
|
-
this.config = {
|
|
56
|
-
overrideConfig: powerbiPlugin.configs.recommended,
|
|
57
|
-
overrideConfigFile: true,
|
|
58
|
-
fix: this.shouldFix,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
}
|
package/lib/Package.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Power BI Visual CLI
|
|
3
|
-
*
|
|
4
|
-
* Copyright (c) Microsoft Corporation
|
|
5
|
-
* All rights reserved.
|
|
6
|
-
* MIT License
|
|
7
|
-
*
|
|
8
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
-
* of this software and associated documentation files (the ""Software""), to deal
|
|
10
|
-
* in the Software without restriction, including without limitation the rights
|
|
11
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
13
|
-
* furnished to do so, subject to the following conditions:
|
|
14
|
-
*
|
|
15
|
-
* The above copyright notice and this permission notice shall be included in
|
|
16
|
-
* all copies or substantial portions of the Software.
|
|
17
|
-
*
|
|
18
|
-
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
24
|
-
* THE SOFTWARE.
|
|
25
|
-
*/
|
|
26
|
-
"use strict";
|
|
27
|
-
import isMatch from "lodash.ismatch";
|
|
28
|
-
/**
|
|
29
|
-
* Represents an instance of a visual package based on file path
|
|
30
|
-
*/
|
|
31
|
-
export default class Package {
|
|
32
|
-
sourceCode;
|
|
33
|
-
capabilities;
|
|
34
|
-
visualFeatureType;
|
|
35
|
-
constructor(sourceCode, capabilities, visualFeatureType) {
|
|
36
|
-
this.sourceCode = sourceCode;
|
|
37
|
-
this.capabilities = capabilities;
|
|
38
|
-
this.visualFeatureType = visualFeatureType;
|
|
39
|
-
}
|
|
40
|
-
contain(keyword) {
|
|
41
|
-
return this.sourceCode.includes(keyword);
|
|
42
|
-
}
|
|
43
|
-
isCapabilityEnabled(expectedObject) {
|
|
44
|
-
return isMatch(this.capabilities, expectedObject);
|
|
45
|
-
}
|
|
46
|
-
}
|
package/lib/TemplateFetcher.js
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
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 = await readJsonFromRoot('config.json');
|
|
9
|
-
export default class TemplateFetcher {
|
|
10
|
-
templateName;
|
|
11
|
-
visualName;
|
|
12
|
-
folderName;
|
|
13
|
-
apiVersion;
|
|
14
|
-
constructor(templateName, visualName, apiVersion) {
|
|
15
|
-
this.templateName = templateName;
|
|
16
|
-
this.visualName = visualName;
|
|
17
|
-
this.folderName = `${this.visualName}`;
|
|
18
|
-
this.apiVersion = apiVersion;
|
|
19
|
-
}
|
|
20
|
-
fetch() {
|
|
21
|
-
const folder = createFolder.call(this, this.folderName);
|
|
22
|
-
download.call(this, config.visualTemplates[this.templateName], path.join(folder, "template.zip"))
|
|
23
|
-
.then(this.extractFiles.bind(this))
|
|
24
|
-
.then(this.removeZipFile.bind(this))
|
|
25
|
-
.then(this.setVisualGUID.bind(this))
|
|
26
|
-
.then(this.setApiVersion.bind(this))
|
|
27
|
-
.then(this.runNpmInstall.bind(this))
|
|
28
|
-
.then(this.showNextSteps.bind(this));
|
|
29
|
-
}
|
|
30
|
-
async removeZipFile() {
|
|
31
|
-
const folder = path.join("./", this.folderName);
|
|
32
|
-
const fileName = path.join(folder, "template.zip");
|
|
33
|
-
await fs.unlink(`.${path.sep}${fileName}`, (err) => {
|
|
34
|
-
if (err) {
|
|
35
|
-
ConsoleWriter.warning(`.${path.sep}${fileName} was not deleted`);
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
async extractFiles(file) {
|
|
40
|
-
const filePath = path.join(process.cwd(), file.path);
|
|
41
|
-
const buffer = await fs.readFile(filePath);
|
|
42
|
-
const zip = await JSZip.loadAsync(buffer);
|
|
43
|
-
const filesList = Object.keys(zip.files);
|
|
44
|
-
for (const filename of filesList) {
|
|
45
|
-
if (filename[filename.length - 1] === "/") {
|
|
46
|
-
// generate folders for exclude parent folder
|
|
47
|
-
const dest = path.join(path.dirname(filePath), path.join(filename, ".."));
|
|
48
|
-
await fs.ensureDir(dest);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
// write files into dirs for exclude parent folder
|
|
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');
|
|
54
|
-
await fs.writeFile(dest, content);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
async setApiVersion() {
|
|
59
|
-
if (!this.apiVersion) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
ConsoleWriter.info(`Set Visual API to ${this.apiVersion}`);
|
|
63
|
-
const packageJsonFile = path.join(process.cwd(), this.folderName, "package.json");
|
|
64
|
-
const packageJson = await fs.readJson(packageJsonFile);
|
|
65
|
-
if (packageJson.devDependencies && packageJson.devDependencies["powerbi-visuals-api"]) {
|
|
66
|
-
packageJson.devDependencies["powerbi-visuals-api"] = `~${this.apiVersion}`;
|
|
67
|
-
}
|
|
68
|
-
if (packageJson.dependencies && packageJson.dependencies["powerbi-visuals-api"]) {
|
|
69
|
-
packageJson.dependencies["powerbi-visuals-api"] = `~${this.apiVersion}`;
|
|
70
|
-
}
|
|
71
|
-
await fs.writeJSON(packageJsonFile, packageJson);
|
|
72
|
-
}
|
|
73
|
-
async setVisualGUID() {
|
|
74
|
-
const pbivizJsonFile = path.join(process.cwd(), this.folderName, "pbiviz.json");
|
|
75
|
-
const pbivizJson = await fs.readJson(pbivizJsonFile);
|
|
76
|
-
pbivizJson.visual.guid = this.visualName + VisualGenerator.generateVisualGuid();
|
|
77
|
-
await fs.writeJSON(pbivizJsonFile, pbivizJson);
|
|
78
|
-
}
|
|
79
|
-
runNpmInstall() {
|
|
80
|
-
return new Promise((resolve, reject) => {
|
|
81
|
-
ConsoleWriter.info("Installing packages...");
|
|
82
|
-
process.chdir(this.folderName);
|
|
83
|
-
// const { stdout, stderr } = await exec('ls');
|
|
84
|
-
const child = exec('npm install', (error, stdout, stderr) => {
|
|
85
|
-
if (error) {
|
|
86
|
-
ConsoleWriter.error(error.stack);
|
|
87
|
-
ConsoleWriter.error(`Error code: ${error.code}`);
|
|
88
|
-
ConsoleWriter.error(`Signal received: ${error.signal}`);
|
|
89
|
-
}
|
|
90
|
-
ConsoleWriter.warning(stderr);
|
|
91
|
-
ConsoleWriter.info(stdout);
|
|
92
|
-
resolve(true);
|
|
93
|
-
});
|
|
94
|
-
child.on("error", (er) => {
|
|
95
|
-
ConsoleWriter.error(er);
|
|
96
|
-
reject();
|
|
97
|
-
});
|
|
98
|
-
child.on("exit", (code) => {
|
|
99
|
-
if (code !== 0) {
|
|
100
|
-
ConsoleWriter.error(`npm install stopped with code ${code}`);
|
|
101
|
-
reject();
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
showNextSteps() {
|
|
107
|
-
ConsoleWriter.blank();
|
|
108
|
-
ConsoleWriter.info("Run `npm run start` to start visual development");
|
|
109
|
-
ConsoleWriter.info("Run `npm run package` to create visual package");
|
|
110
|
-
}
|
|
111
|
-
}
|
package/lib/Visual.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { compareVersions } from "compare-versions";
|
|
2
|
-
import { VisualFeatureType } from "./features/FeatureTypes.js";
|
|
3
|
-
export class Visual {
|
|
4
|
-
visualFeatureType;
|
|
5
|
-
capabilities;
|
|
6
|
-
config;
|
|
7
|
-
visualVersion;
|
|
8
|
-
constructor(capabilities, config) {
|
|
9
|
-
this.capabilities = capabilities;
|
|
10
|
-
this.config = config;
|
|
11
|
-
this.visualFeatureType = this.getVisualFeatureType();
|
|
12
|
-
this.visualVersion = config.visual.version;
|
|
13
|
-
}
|
|
14
|
-
doesAPIVersionMatch(minAPIversion) {
|
|
15
|
-
return compareVersions(this.config.apiVersion ?? minAPIversion, minAPIversion) !== -1;
|
|
16
|
-
}
|
|
17
|
-
isVisualVersionValid(length) {
|
|
18
|
-
return this.visualVersion.split(".").length === length;
|
|
19
|
-
}
|
|
20
|
-
getVisualFeatureType() {
|
|
21
|
-
const isMatrixSupported = this.capabilities?.dataViewMappings?.some(dataView => dataView.matrix);
|
|
22
|
-
const isSlicer = Boolean(this.capabilities?.objects?.general?.properties?.filter?.type?.filter);
|
|
23
|
-
let type = isSlicer ? VisualFeatureType.Slicer : VisualFeatureType.NonSlicer;
|
|
24
|
-
if (isMatrixSupported) {
|
|
25
|
-
type = type | VisualFeatureType.Matrix;
|
|
26
|
-
}
|
|
27
|
-
return type;
|
|
28
|
-
}
|
|
29
|
-
}
|