source-map-explorer 2.3.0 → 2.4.2
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/README.md +19 -7
- package/dist/api.d.ts +1 -7
- package/dist/api.js +49 -84
- package/dist/api.js.map +1 -0
- package/dist/app-error.d.ts +1 -1
- package/dist/app-error.js +13 -34
- package/dist/app-error.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +58 -93
- package/dist/cli.js.map +1 -0
- package/dist/coverage.d.ts +1 -10
- package/dist/coverage.js +27 -125
- package/dist/coverage.js.map +1 -0
- package/dist/explore.d.ts +1 -4
- package/dist/explore.js +118 -150
- package/dist/explore.js.map +1 -0
- package/dist/helpers.d.ts +2 -16
- package/dist/helpers.js +35 -68
- package/dist/helpers.js.map +1 -0
- package/dist/html.d.ts +1 -7
- package/dist/html.js +68 -95
- package/dist/html.js.map +1 -0
- package/dist/index.d.ts +2 -90
- package/dist/index.js +9 -37
- package/dist/index.js.map +1 -0
- package/dist/output.d.ts +1 -1
- package/dist/output.js +21 -53
- package/dist/output.js.map +1 -0
- package/dist/types.d.ts +121 -0
- package/package.json +49 -50
package/dist/html.js
CHANGED
@@ -1,51 +1,33 @@
|
|
1
1
|
'use strict';
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
}
|
6
|
-
|
7
|
-
exports
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
var _path = _interopRequireDefault(require('path'));
|
16
|
-
|
17
|
-
var _escapeHtml = _interopRequireDefault(require('escape-html'));
|
18
|
-
|
19
|
-
var _helpers = require('./helpers');
|
20
|
-
|
21
|
-
var _coverage = require('./coverage');
|
22
|
-
|
23
|
-
function _interopRequireDefault(obj) {
|
24
|
-
return obj && obj.__esModule ? obj : { default: obj };
|
25
|
-
}
|
26
|
-
|
27
|
-
/**
|
28
|
-
* Generate HTML file content for specified files
|
29
|
-
*/
|
2
|
+
var __importDefault =
|
3
|
+
(this && this.__importDefault) ||
|
4
|
+
function (mod) {
|
5
|
+
return mod && mod.__esModule ? mod : { default: mod };
|
6
|
+
};
|
7
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
8
|
+
const btoa_1 = __importDefault(require('btoa'));
|
9
|
+
const ejs_1 = __importDefault(require('ejs'));
|
10
|
+
const fs_1 = __importDefault(require('fs'));
|
11
|
+
const path_1 = __importDefault(require('path'));
|
12
|
+
const escape_html_1 = __importDefault(require('escape-html'));
|
13
|
+
const helpers_1 = require('./helpers');
|
14
|
+
const coverage_1 = require('./coverage');
|
30
15
|
function generateHtml(exploreResults, options) {
|
31
16
|
const assets = {
|
32
|
-
webtreemapJs:
|
33
|
-
|
17
|
+
webtreemapJs: btoa_1.default(
|
18
|
+
fs_1.default.readFileSync(require.resolve('./vendor/webtreemap.js'))
|
34
19
|
),
|
35
|
-
webtreemapCss:
|
36
|
-
|
20
|
+
webtreemapCss: btoa_1.default(
|
21
|
+
fs_1.default.readFileSync(require.resolve('./vendor/webtreemap.css'))
|
37
22
|
),
|
38
|
-
};
|
39
|
-
|
23
|
+
};
|
40
24
|
if (exploreResults.length > 1) {
|
41
25
|
exploreResults = [makeMergedBundle(exploreResults)].concat(exploreResults);
|
42
|
-
}
|
43
|
-
|
44
|
-
const bundles = exploreResults.map(data => ({
|
26
|
+
}
|
27
|
+
const bundles = exploreResults.map((data) => ({
|
45
28
|
name: data.bundleName,
|
46
|
-
size:
|
47
|
-
}));
|
48
|
-
|
29
|
+
size: helpers_1.formatBytes(data.totalBytes),
|
30
|
+
}));
|
49
31
|
const treeDataMap = exploreResults.reduce((result, data, index) => {
|
50
32
|
result[index] = {
|
51
33
|
name: data.bundleName,
|
@@ -53,8 +35,8 @@ function generateHtml(exploreResults, options) {
|
|
53
35
|
};
|
54
36
|
return result;
|
55
37
|
}, {});
|
56
|
-
const template =
|
57
|
-
return
|
38
|
+
const template = helpers_1.getFileContent(path_1.default.join(__dirname, 'tree-viz.ejs'));
|
39
|
+
return ejs_1.default.render(template, {
|
58
40
|
options,
|
59
41
|
bundles,
|
60
42
|
treeDataMap,
|
@@ -62,16 +44,11 @@ function generateHtml(exploreResults, options) {
|
|
62
44
|
webtreemapCss: assets.webtreemapCss,
|
63
45
|
});
|
64
46
|
}
|
65
|
-
|
66
|
-
* Create a combined result where each of the inputs is a separate node under the root
|
67
|
-
*/
|
68
|
-
|
47
|
+
exports.generateHtml = generateHtml;
|
69
48
|
function makeMergedBundle(exploreResults) {
|
70
49
|
let totalBytes = 0;
|
71
|
-
const files = {};
|
72
|
-
|
73
|
-
const commonPrefix = (0, _helpers.getCommonPathPrefix)(exploreResults.map(r => r.bundleName));
|
74
|
-
|
50
|
+
const files = {};
|
51
|
+
const commonPrefix = helpers_1.getCommonPathPrefix(exploreResults.map((r) => r.bundleName));
|
75
52
|
for (const result of exploreResults) {
|
76
53
|
totalBytes += result.totalBytes;
|
77
54
|
const prefix = result.bundleName.slice(commonPrefix.length);
|
@@ -79,7 +56,6 @@ function makeMergedBundle(exploreResults) {
|
|
79
56
|
files[`${prefix}/${fileName}`] = size;
|
80
57
|
});
|
81
58
|
}
|
82
|
-
|
83
59
|
return {
|
84
60
|
bundleName: '[combined]',
|
85
61
|
totalBytes,
|
@@ -89,114 +65,111 @@ function makeMergedBundle(exploreResults) {
|
|
89
65
|
files,
|
90
66
|
};
|
91
67
|
}
|
92
|
-
|
68
|
+
function getNodePath(parts, depthIndex) {
|
69
|
+
return parts.slice(0, depthIndex + 1).join('/');
|
70
|
+
}
|
71
|
+
const WEBPACK_FILENAME_PREFIX = 'webpack:///';
|
72
|
+
const WEBPACK_FILENAME_PREFIX_LENGTH = WEBPACK_FILENAME_PREFIX.length;
|
73
|
+
function splitFilename(file) {
|
74
|
+
const webpackPrefixIndex = file.indexOf(WEBPACK_FILENAME_PREFIX);
|
75
|
+
if (webpackPrefixIndex !== -1) {
|
76
|
+
return [
|
77
|
+
...file.substring(0, webpackPrefixIndex).split('/'),
|
78
|
+
WEBPACK_FILENAME_PREFIX,
|
79
|
+
...file.substring(webpackPrefixIndex + WEBPACK_FILENAME_PREFIX_LENGTH).split('/'),
|
80
|
+
].filter(Boolean);
|
81
|
+
}
|
82
|
+
return file.split('/');
|
83
|
+
}
|
93
84
|
function getTreeNodesMap(fileDataMap) {
|
94
|
-
let partsSourceTuples = Object.keys(fileDataMap).map(file => [file
|
85
|
+
let partsSourceTuples = Object.keys(fileDataMap).map((file) => [splitFilename(file), file]);
|
95
86
|
const maxDepth = Math.max(...partsSourceTuples.map(([parts]) => parts.length));
|
96
|
-
|
97
87
|
for (let depthIndex = 0; depthIndex < maxDepth; depthIndex += 1) {
|
98
|
-
partsSourceTuples = partsSourceTuples.map(([parts, file]) => {
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
88
|
+
partsSourceTuples = partsSourceTuples.map(([parts, file], currentNodeIndex) => {
|
89
|
+
if (parts[depthIndex]) {
|
90
|
+
const nodePath = getNodePath(parts, depthIndex);
|
91
|
+
const hasSameRootPaths = partsSourceTuples.some(([pathParts], index) => {
|
92
|
+
if (index === currentNodeIndex) {
|
93
|
+
return false;
|
94
|
+
}
|
95
|
+
if (!pathParts[depthIndex]) {
|
96
|
+
return false;
|
97
|
+
}
|
98
|
+
return getNodePath(pathParts, depthIndex) === nodePath;
|
99
|
+
});
|
100
|
+
if (!hasSameRootPaths) {
|
108
101
|
return [[...parts.slice(0, depthIndex), parts.slice(depthIndex).join('/')], file];
|
109
102
|
}
|
110
103
|
}
|
111
|
-
|
112
104
|
return [parts, file];
|
113
105
|
});
|
114
106
|
}
|
115
|
-
|
116
107
|
return partsSourceTuples.reduce((result, [parts, file]) => {
|
117
108
|
result[file] = parts;
|
118
109
|
return result;
|
119
110
|
}, {});
|
120
111
|
}
|
121
|
-
|
122
|
-
/**
|
123
|
-
* Convert file size map to webtreemap data
|
124
|
-
*/
|
125
112
|
function getWebTreeMapData(files) {
|
126
113
|
const treeNodesMap = getTreeNodesMap(files);
|
127
114
|
const treeData = newNode('/');
|
128
|
-
|
129
115
|
for (const source in files) {
|
130
116
|
addNode(treeNodesMap[source], files[source], treeData);
|
131
117
|
}
|
132
|
-
|
133
118
|
addSizeToTitle(treeData, treeData.data['$area']);
|
134
119
|
return treeData;
|
135
120
|
}
|
136
|
-
|
121
|
+
exports.getWebTreeMapData = getWebTreeMapData;
|
137
122
|
function newNode(name) {
|
138
123
|
return {
|
139
|
-
name:
|
124
|
+
name: escape_html_1.default(name),
|
140
125
|
data: {
|
141
126
|
$area: 0,
|
142
127
|
},
|
143
128
|
};
|
144
129
|
}
|
145
|
-
|
146
130
|
function setNodeData(node, fileData) {
|
147
131
|
const size = node.data['$area'] + fileData.size;
|
148
|
-
|
149
132
|
if (fileData.coveredSize !== undefined) {
|
150
133
|
const coveredSize = (node.data.coveredSize || 0) + fileData.coveredSize;
|
151
134
|
node.data.coveredSize = coveredSize;
|
152
|
-
node.data.backgroundColor =
|
135
|
+
node.data.backgroundColor = coverage_1.getColorByPercent(coveredSize / size);
|
153
136
|
}
|
154
|
-
|
155
137
|
node.data['$area'] = size;
|
156
138
|
}
|
157
|
-
|
158
139
|
function addNode(parts, fileData, treeData) {
|
159
|
-
// No need to create nodes with zero size (e.g. '[unmapped]')
|
160
140
|
if (fileData.size === 0) {
|
161
141
|
return;
|
162
142
|
}
|
163
|
-
|
164
143
|
let node = treeData;
|
165
144
|
setNodeData(node, fileData);
|
166
|
-
parts.forEach(part => {
|
145
|
+
parts.forEach((part) => {
|
167
146
|
if (!node.children) {
|
168
147
|
node.children = [];
|
169
148
|
}
|
170
|
-
|
171
|
-
let child = node.children.find(child => child.name === part);
|
172
|
-
|
149
|
+
let child = node.children.find((child) => child.name === part);
|
173
150
|
if (!child) {
|
174
151
|
child = newNode(part);
|
175
152
|
node.children.push(child);
|
176
153
|
}
|
177
|
-
|
178
154
|
node = child;
|
179
155
|
setNodeData(child, fileData);
|
180
156
|
});
|
181
157
|
}
|
182
|
-
|
183
158
|
function addSizeToTitle(node, total) {
|
184
159
|
const { $area: size, coveredSize } = node.data;
|
185
160
|
const titleParts = [
|
186
161
|
node.name,
|
187
|
-
|
188
|
-
`${
|
189
|
-
];
|
190
|
-
|
162
|
+
helpers_1.formatBytes(size),
|
163
|
+
`${helpers_1.formatPercent(size, total, 1)}%`,
|
164
|
+
];
|
191
165
|
if (coveredSize !== undefined && node.children === undefined) {
|
192
|
-
titleParts.push(`Coverage: ${
|
166
|
+
titleParts.push(`Coverage: ${helpers_1.formatPercent(coveredSize, size, 1)}%`);
|
193
167
|
}
|
194
|
-
|
195
168
|
node.name = titleParts.join(' • ');
|
196
|
-
|
197
169
|
if (node.children) {
|
198
|
-
node.children.forEach(child => {
|
170
|
+
node.children.forEach((child) => {
|
199
171
|
addSizeToTitle(child, total);
|
200
172
|
});
|
201
173
|
}
|
202
174
|
}
|
175
|
+
//# sourceMappingURL=html.js.map
|
package/dist/html.js.map
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":";;;;;AAAA,gDAAwB;AACxB,8CAAsB;AACtB,4CAAoB;AACpB,gDAAwB;AACxB,8DAAqC;AAErC,uCAA4F;AAC5F,yCAA+C;AAO/C,SAAgB,YAAY,CAC1B,cAAqC,EACrC,OAAuB;IAEvB,MAAM,MAAM,GAAG;QACb,YAAY,EAAE,cAAI,CAAC,YAAE,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,CAAC;QAC9E,aAAa,EAAE,cAAI,CAAC,YAAE,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC;KACjF,CAAC;IAGF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;QAC7B,cAAc,GAAG,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;KAC5E;IAGD,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC5C,IAAI,EAAE,IAAI,CAAC,UAAU;QACrB,IAAI,EAAE,qBAAW,CAAC,IAAI,CAAC,UAAU,CAAC;KACnC,CAAC,CAAC,CAAC;IAGJ,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CACvC,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACtB,MAAM,CAAC,KAAK,CAAC,GAAG;YACd,IAAI,EAAE,IAAI,CAAC,UAAU;YACrB,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC;SACpC,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC,EACD,EAAE,CACH,CAAC;IACF,MAAM,QAAQ,GAAG,wBAAc,CAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;IAEtE,OAAO,aAAG,CAAC,MAAM,CAAC,QAAQ,EAAE;QAC1B,OAAO;QACP,OAAO;QACP,WAAW;QACX,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,aAAa,EAAE,MAAM,CAAC,aAAa;KACpC,CAAC,CAAC;AACL,CAAC;AAzCD,oCAyCC;AAKD,SAAS,gBAAgB,CAAC,cAAqC;IAC7D,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,MAAM,KAAK,GAAgB,EAAE,CAAC;IAG9B,MAAM,YAAY,GAAG,6BAAmB,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IAElF,KAAK,MAAM,MAAM,IAAI,cAAc,EAAE;QACnC,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC;QAEhC,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAE5D,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE;YACxD,KAAK,CAAC,GAAG,MAAM,IAAI,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC;QACxC,CAAC,CAAC,CAAC;KACJ;IAED,OAAO;QACL,UAAU,EAAE,YAAY;QACxB,UAAU;QACV,WAAW,EAAE,CAAC;QACd,QAAQ,EAAE,CAAC;QACX,qBAAqB,EAAE,CAAC;QACxB,KAAK;KACN,CAAC;AACJ,CAAC;AAID,SAAS,WAAW,CAAC,KAAe,EAAE,UAAkB;IACtD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,uBAAuB,GAAG,aAAa,CAAC;AAC9C,MAAM,8BAA8B,GAAG,uBAAuB,CAAC,MAAM,CAAC;AAEtE,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAGjE,IAAI,kBAAkB,KAAK,CAAC,CAAC,EAAE;QAC7B,OAAO;YACL,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;YACnD,uBAAuB;YACvB,GAAG,IAAI,CAAC,SAAS,CAAC,kBAAkB,GAAG,8BAA8B,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;SAClF,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;KACnB;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,eAAe,CAAC,WAAwB;IAC/C,IAAI,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAqB,CAAC,IAAI,EAAE,EAAE,CAAC;QACjF,aAAa,CAAC,IAAI,CAAC;QACnB,IAAI;KACL,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAE/E,KAAK,IAAI,UAAU,GAAG,CAAC,EAAE,UAAU,GAAG,QAAQ,EAAE,UAAU,IAAI,CAAC,EAAE;QAC/D,iBAAiB,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,gBAAgB,EAAE,EAAE;YAC5E,IAAI,KAAK,CAAC,UAAU,CAAC,EAAE;gBACrB,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBAEhD,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE;oBACrE,IAAI,KAAK,KAAK,gBAAgB,EAAE;wBAC9B,OAAO,KAAK,CAAC;qBACd;oBACD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE;wBAC1B,OAAO,KAAK,CAAC;qBACd;oBAED,OAAO,WAAW,CAAC,SAAS,EAAE,UAAU,CAAC,KAAK,QAAQ,CAAC;gBACzD,CAAC,CAAC,CAAC;gBAEH,IAAI,CAAC,gBAAgB,EAAE;oBAErB,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;iBACnF;aACF;YAED,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;KACJ;IAED,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;QACxD,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QAErB,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AAeD,SAAgB,iBAAiB,CAAC,KAAkB;IAClD,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAE9B,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE;QAC1B,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC;KACxD;IAED,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAEjD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAXD,8CAWC;AAED,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO;QACL,IAAI,EAAE,qBAAU,CAAC,IAAI,CAAC;QACtB,IAAI,EAAE;YACJ,KAAK,EAAE,CAAC;SACT;KACF,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,IAAoB,EAAE,QAAkB;IAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC;IAEhD,IAAI,QAAQ,CAAC,WAAW,KAAK,SAAS,EAAE;QACtC,MAAM,WAAW,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC;QAExE,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,eAAe,GAAG,4BAAiB,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;KACnE;IAED,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;AAC5B,CAAC;AAED,SAAS,OAAO,CAAC,KAAe,EAAE,QAAkB,EAAE,QAAwB;IAE5E,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE;QACvB,OAAO;KACR;IAED,IAAI,IAAI,GAAG,QAAQ,CAAC;IAEpB,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAE5B,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACrB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAClB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;SACpB;QAED,IAAI,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAE/D,IAAI,CAAC,KAAK,EAAE;YACV,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SAC3B;QAED,IAAI,GAAG,KAAK,CAAC;QAEb,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,cAAc,CAAC,IAAoB,EAAE,KAAa;IACzD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;IAE/C,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,qBAAW,CAAC,IAAI,CAAC,EAAE,GAAG,uBAAa,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IAGvF,IAAI,WAAW,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;QAC5D,UAAU,CAAC,IAAI,CAAC,aAAa,uBAAa,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;KACtE;IAED,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEnC,IAAI,IAAI,CAAC,QAAQ,EAAE;QACjB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAC9B,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;KACJ;AACH,CAAC","sourcesContent":["import btoa from 'btoa';\nimport ejs from 'ejs';\nimport fs from 'fs';\nimport path from 'path';\nimport escapeHtml from 'escape-html';\n\nimport { formatBytes, getCommonPathPrefix, getFileContent, formatPercent } from './helpers';\nimport { getColorByPercent } from './coverage';\n\nimport type { ExploreOptions, ExploreBundleResult, FileData, FileDataMap } from './types';\n\n/**\n * Generate HTML file content for specified files\n */\nexport function generateHtml(\n exploreResults: ExploreBundleResult[],\n options: ExploreOptions\n): string {\n const assets = {\n webtreemapJs: btoa(fs.readFileSync(require.resolve('./vendor/webtreemap.js'))),\n webtreemapCss: btoa(fs.readFileSync(require.resolve('./vendor/webtreemap.css'))),\n };\n\n // Create a combined bundle if applicable\n if (exploreResults.length > 1) {\n exploreResults = [makeMergedBundle(exploreResults)].concat(exploreResults);\n }\n\n // Get bundles info to generate select element\n const bundles = exploreResults.map((data) => ({\n name: data.bundleName,\n size: formatBytes(data.totalBytes),\n }));\n\n // Get webtreemap data to update map on bundle select\n const treeDataMap = exploreResults.reduce<Record<string, { name: string; data: WebTreeMapNode }>>(\n (result, data, index) => {\n result[index] = {\n name: data.bundleName,\n data: getWebTreeMapData(data.files),\n };\n\n return result;\n },\n {}\n );\n const template = getFileContent(path.join(__dirname, 'tree-viz.ejs'));\n\n return ejs.render(template, {\n options,\n bundles,\n treeDataMap,\n webtreemapJs: assets.webtreemapJs,\n webtreemapCss: assets.webtreemapCss,\n });\n}\n\n/**\n * Create a combined result where each of the inputs is a separate node under the root\n */\nfunction makeMergedBundle(exploreResults: ExploreBundleResult[]): ExploreBundleResult {\n let totalBytes = 0;\n const files: FileDataMap = {};\n\n // Remove any common prefix to keep the visualization as simple as possible.\n const commonPrefix = getCommonPathPrefix(exploreResults.map((r) => r.bundleName));\n\n for (const result of exploreResults) {\n totalBytes += result.totalBytes;\n\n const prefix = result.bundleName.slice(commonPrefix.length);\n\n Object.entries(result.files).forEach(([fileName, size]) => {\n files[`${prefix}/${fileName}`] = size;\n });\n }\n\n return {\n bundleName: '[combined]',\n totalBytes,\n mappedBytes: 0,\n eolBytes: 0,\n sourceMapCommentBytes: 0,\n files,\n };\n}\n\ntype TreeNodesMap = { [source: string]: string[] };\n\nfunction getNodePath(parts: string[], depthIndex: number): string {\n return parts.slice(0, depthIndex + 1).join('/');\n}\n\nconst WEBPACK_FILENAME_PREFIX = 'webpack:///';\nconst WEBPACK_FILENAME_PREFIX_LENGTH = WEBPACK_FILENAME_PREFIX.length;\n\nfunction splitFilename(file: string): string[] {\n const webpackPrefixIndex = file.indexOf(WEBPACK_FILENAME_PREFIX);\n\n // Treat webpack file prefix as a filename part\n if (webpackPrefixIndex !== -1) {\n return [\n ...file.substring(0, webpackPrefixIndex).split('/'),\n WEBPACK_FILENAME_PREFIX,\n ...file.substring(webpackPrefixIndex + WEBPACK_FILENAME_PREFIX_LENGTH).split('/'),\n ].filter(Boolean);\n }\n\n return file.split('/');\n}\n\nfunction getTreeNodesMap(fileDataMap: FileDataMap): TreeNodesMap {\n let partsSourceTuples = Object.keys(fileDataMap).map<[string[], string]>((file) => [\n splitFilename(file),\n file,\n ]);\n\n const maxDepth = Math.max(...partsSourceTuples.map(([parts]) => parts.length));\n\n for (let depthIndex = 0; depthIndex < maxDepth; depthIndex += 1) {\n partsSourceTuples = partsSourceTuples.map(([parts, file], currentNodeIndex) => {\n if (parts[depthIndex]) {\n const nodePath = getNodePath(parts, depthIndex);\n\n const hasSameRootPaths = partsSourceTuples.some(([pathParts], index) => {\n if (index === currentNodeIndex) {\n return false;\n }\n if (!pathParts[depthIndex]) {\n return false;\n }\n\n return getNodePath(pathParts, depthIndex) === nodePath;\n });\n\n if (!hasSameRootPaths) {\n // Collapse non-contributing path parts\n return [[...parts.slice(0, depthIndex), parts.slice(depthIndex).join('/')], file];\n }\n }\n\n return [parts, file];\n });\n }\n\n return partsSourceTuples.reduce((result, [parts, file]) => {\n result[file] = parts;\n\n return result;\n }, {});\n}\n\ninterface WebTreeMapNode {\n name: string;\n data: {\n $area: number;\n coveredSize?: number;\n backgroundColor?: string;\n };\n children?: WebTreeMapNode[];\n}\n\n/**\n * Convert file size map to webtreemap data\n */\nexport function getWebTreeMapData(files: FileDataMap): WebTreeMapNode {\n const treeNodesMap = getTreeNodesMap(files);\n const treeData = newNode('/');\n\n for (const source in files) {\n addNode(treeNodesMap[source], files[source], treeData);\n }\n\n addSizeToTitle(treeData, treeData.data['$area']);\n\n return treeData;\n}\n\nfunction newNode(name: string): WebTreeMapNode {\n return {\n name: escapeHtml(name),\n data: {\n $area: 0,\n },\n };\n}\n\nfunction setNodeData(node: WebTreeMapNode, fileData: FileData): void {\n const size = node.data['$area'] + fileData.size;\n\n if (fileData.coveredSize !== undefined) {\n const coveredSize = (node.data.coveredSize || 0) + fileData.coveredSize;\n\n node.data.coveredSize = coveredSize;\n node.data.backgroundColor = getColorByPercent(coveredSize / size);\n }\n\n node.data['$area'] = size;\n}\n\nfunction addNode(parts: string[], fileData: FileData, treeData: WebTreeMapNode): void {\n // No need to create nodes with zero size (e.g. '[unmapped]')\n if (fileData.size === 0) {\n return;\n }\n\n let node = treeData;\n\n setNodeData(node, fileData);\n\n parts.forEach((part) => {\n if (!node.children) {\n node.children = [];\n }\n\n let child = node.children.find((child) => child.name === part);\n\n if (!child) {\n child = newNode(part);\n node.children.push(child);\n }\n\n node = child;\n\n setNodeData(child, fileData);\n });\n}\n\nfunction addSizeToTitle(node: WebTreeMapNode, total: number): void {\n const { $area: size, coveredSize } = node.data;\n\n const titleParts = [node.name, formatBytes(size), `${formatPercent(size, total, 1)}%`];\n\n // Add coverage label to leaf nodes only\n if (coveredSize !== undefined && node.children === undefined) {\n titleParts.push(`Coverage: ${formatPercent(coveredSize, size, 1)}%`);\n }\n\n node.name = titleParts.join(' • ');\n\n if (node.children) {\n node.children.forEach((child) => {\n addSizeToTitle(child, total);\n });\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
@@ -1,92 +1,4 @@
|
|
1
|
-
/// <reference types="node" />
|
2
1
|
import { explore } from './api';
|
3
|
-
|
4
|
-
export { explore
|
2
|
+
export { UNMAPPED_KEY, SOURCE_MAP_COMMENT_KEY, NO_SOURCE_KEY } from './explore';
|
3
|
+
export { explore };
|
5
4
|
export default explore;
|
6
|
-
export interface FileData {
|
7
|
-
size: number;
|
8
|
-
coveredSize?: number;
|
9
|
-
}
|
10
|
-
export declare type FileDataMap = Record<string, FileData>;
|
11
|
-
export interface FileSizes {
|
12
|
-
files: FileDataMap;
|
13
|
-
mappedBytes: number;
|
14
|
-
unmappedBytes?: number;
|
15
|
-
eolBytes: number;
|
16
|
-
sourceMapCommentBytes: number;
|
17
|
-
totalBytes: number;
|
18
|
-
}
|
19
|
-
export declare type ErrorCode = 'Unknown' | 'NoBundles' | 'NoSourceMap' | 'OneSourceSourceMap' | 'UnmappedBytes' | 'InvalidMappingLine' | 'InvalidMappingColumn' | 'CannotSaveFile' | 'CannotCreateTempFile' | 'CannotOpenTempFile' | 'CannotOpenCoverageFile' | 'NoCoverageMatches';
|
20
|
-
export declare type File = string | Buffer;
|
21
|
-
export declare type ReplaceMap = Record<string, string>;
|
22
|
-
export declare type OutputFormat = 'json' | 'tsv' | 'html';
|
23
|
-
/** Represents single bundle */
|
24
|
-
export interface Bundle {
|
25
|
-
code: File;
|
26
|
-
map?: File;
|
27
|
-
coverageRanges?: ColumnsRange[][];
|
28
|
-
}
|
29
|
-
export interface ExploreOptions {
|
30
|
-
/** Exclude "unmapped" bytes from the output */
|
31
|
-
onlyMapped?: boolean;
|
32
|
-
/** Exclude source map comment size from output */
|
33
|
-
excludeSourceMapComment?: boolean;
|
34
|
-
/** Output result as a string */
|
35
|
-
output?: {
|
36
|
-
format: OutputFormat;
|
37
|
-
/** Filename to save output to */
|
38
|
-
filename?: string;
|
39
|
-
};
|
40
|
-
/** Disable removing prefix shared by all sources */
|
41
|
-
noRoot?: boolean;
|
42
|
-
/** Replace "this" by "that" map */
|
43
|
-
replaceMap?: ReplaceMap;
|
44
|
-
coverage?: string;
|
45
|
-
/** Calculate gzip size. Setting it to `true` will also set `onlyMapped` to `true` */
|
46
|
-
gzip?: boolean;
|
47
|
-
}
|
48
|
-
export interface ExploreResult {
|
49
|
-
bundles: ExploreBundleResult[];
|
50
|
-
/** Result as a string - either JSON, TSV or HTML */
|
51
|
-
output?: string;
|
52
|
-
errors: ExploreErrorResult[];
|
53
|
-
}
|
54
|
-
export interface ExploreBundleResult extends FileSizes {
|
55
|
-
bundleName: string;
|
56
|
-
}
|
57
|
-
export interface ExploreErrorResult {
|
58
|
-
bundleName: string;
|
59
|
-
code: string;
|
60
|
-
message: string;
|
61
|
-
error?: NodeJS.ErrnoException;
|
62
|
-
isWarning?: boolean;
|
63
|
-
}
|
64
|
-
export declare type BundlesAndFileTokens = (Bundle | string)[] | Bundle | string;
|
65
|
-
/** Represents inclusive range (e.g. [0,5] six columns) */
|
66
|
-
export interface ColumnsRange {
|
67
|
-
/** Fist column index */
|
68
|
-
start: number;
|
69
|
-
/** Last column index */
|
70
|
-
end: number;
|
71
|
-
}
|
72
|
-
export interface MappingRange extends ColumnsRange {
|
73
|
-
source: string;
|
74
|
-
}
|
75
|
-
/** Represents exclusive range (e.g. [0,5) - four columns) */
|
76
|
-
export interface Coverage {
|
77
|
-
url: string;
|
78
|
-
ranges: CoverageRange[];
|
79
|
-
/** File content as one line */
|
80
|
-
text: string;
|
81
|
-
}
|
82
|
-
export interface CoverageRange {
|
83
|
-
/** First column index */
|
84
|
-
start: number;
|
85
|
-
/** Column index next after last column index */
|
86
|
-
end: number;
|
87
|
-
}
|
88
|
-
declare module 'source-map' {
|
89
|
-
interface MappingItem {
|
90
|
-
lastGeneratedColumn: number | null;
|
91
|
-
}
|
92
|
-
}
|
package/dist/index.js
CHANGED
@@ -1,38 +1,10 @@
|
|
1
1
|
'use strict';
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
});
|
12
|
-
Object.defineProperty(exports, 'UNMAPPED_KEY', {
|
13
|
-
enumerable: true,
|
14
|
-
get: function() {
|
15
|
-
return _explore.UNMAPPED_KEY;
|
16
|
-
},
|
17
|
-
});
|
18
|
-
Object.defineProperty(exports, 'SOURCE_MAP_COMMENT_KEY', {
|
19
|
-
enumerable: true,
|
20
|
-
get: function() {
|
21
|
-
return _explore.SOURCE_MAP_COMMENT_KEY;
|
22
|
-
},
|
23
|
-
});
|
24
|
-
Object.defineProperty(exports, 'NO_SOURCE_KEY', {
|
25
|
-
enumerable: true,
|
26
|
-
get: function() {
|
27
|
-
return _explore.NO_SOURCE_KEY;
|
28
|
-
},
|
29
|
-
});
|
30
|
-
exports.default = void 0;
|
31
|
-
|
32
|
-
var _api = require('./api');
|
33
|
-
|
34
|
-
var _explore = require('./explore');
|
35
|
-
|
36
|
-
var _default = _api.explore; // Export all interfaces from index.ts to avoid type exports in compiled js code. See https://github.com/babel/babel/issues/8361
|
37
|
-
|
38
|
-
exports.default = _default;
|
2
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
3
|
+
const api_1 = require('./api');
|
4
|
+
exports.explore = api_1.explore;
|
5
|
+
var explore_1 = require('./explore');
|
6
|
+
exports.UNMAPPED_KEY = explore_1.UNMAPPED_KEY;
|
7
|
+
exports.SOURCE_MAP_COMMENT_KEY = explore_1.SOURCE_MAP_COMMENT_KEY;
|
8
|
+
exports.NO_SOURCE_KEY = explore_1.NO_SOURCE_KEY;
|
9
|
+
exports.default = api_1.explore;
|
10
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,+BAAgC;AAIvB,kBAJA,aAAO,CAIA;AAHhB,qCAAgF;AAAvE,iCAAA,YAAY,CAAA;AAAE,2CAAA,sBAAsB,CAAA;AAAE,kCAAA,aAAa,CAAA;AAI5D,kBAAe,aAAO,CAAC","sourcesContent":["import { explore } from './api';\nexport { UNMAPPED_KEY, SOURCE_MAP_COMMENT_KEY, NO_SOURCE_KEY } from './explore';\n\n// Provide both default and named export for convenience\nexport { explore };\nexport default explore;\n"]}
|
package/dist/output.d.ts
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
import { ExploreBundleResult, ExploreOptions, ExploreResult } from './
|
1
|
+
import type { ExploreBundleResult, ExploreOptions, ExploreResult } from './types';
|
2
2
|
export declare function formatOutput(results: ExploreBundleResult[], options: ExploreOptions): string | undefined;
|
3
3
|
export declare function saveOutputToFile(result: ExploreResult, options: ExploreOptions): void;
|
package/dist/output.js
CHANGED
@@ -1,56 +1,35 @@
|
|
1
1
|
'use strict';
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
}
|
6
|
-
|
7
|
-
exports
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
var _fs = _interopRequireDefault(require('fs'));
|
14
|
-
|
15
|
-
var _html = require('./html');
|
16
|
-
|
17
|
-
var _appError = require('./app-error');
|
18
|
-
|
19
|
-
function _interopRequireDefault(obj) {
|
20
|
-
return obj && obj.__esModule ? obj : { default: obj };
|
21
|
-
}
|
22
|
-
|
2
|
+
var __importDefault =
|
3
|
+
(this && this.__importDefault) ||
|
4
|
+
function (mod) {
|
5
|
+
return mod && mod.__esModule ? mod : { default: mod };
|
6
|
+
};
|
7
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
8
|
+
const os_1 = __importDefault(require('os'));
|
9
|
+
const path_1 = __importDefault(require('path'));
|
10
|
+
const fs_1 = __importDefault(require('fs'));
|
11
|
+
const html_1 = require('./html');
|
12
|
+
const app_error_1 = require('./app-error');
|
23
13
|
function formatOutput(results, options) {
|
24
14
|
if (!options.output) {
|
25
15
|
return;
|
26
16
|
}
|
27
|
-
|
28
17
|
switch (options.output.format) {
|
29
18
|
case 'json':
|
30
|
-
return JSON.stringify(
|
31
|
-
{
|
32
|
-
results,
|
33
|
-
},
|
34
|
-
null,
|
35
|
-
' '
|
36
|
-
);
|
37
|
-
|
19
|
+
return JSON.stringify({ results }, null, ' ');
|
38
20
|
case 'tsv':
|
39
21
|
return outputAsTsv(results);
|
40
|
-
|
41
22
|
case 'html':
|
42
|
-
return
|
23
|
+
return html_1.generateHtml(results, options);
|
43
24
|
}
|
44
25
|
}
|
45
|
-
|
26
|
+
exports.formatOutput = formatOutput;
|
46
27
|
function outputAsTsv(results) {
|
47
28
|
const lines = ['Source\tSize'];
|
48
29
|
results.forEach((bundle, index) => {
|
49
30
|
if (index > 0) {
|
50
|
-
// Separate bundles by empty line
|
51
31
|
lines.push('');
|
52
32
|
}
|
53
|
-
|
54
33
|
Object.entries(bundle.files)
|
55
34
|
.map(([source, data]) => [source, data.size])
|
56
35
|
.sort(sortFilesBySize)
|
@@ -58,37 +37,26 @@ function outputAsTsv(results) {
|
|
58
37
|
lines.push(`${source}\t${size}`);
|
59
38
|
});
|
60
39
|
});
|
61
|
-
return lines.join(
|
40
|
+
return lines.join(os_1.default.EOL);
|
62
41
|
}
|
63
|
-
|
64
42
|
function sortFilesBySize([, aSize], [, bSize]) {
|
65
43
|
return bSize - aSize;
|
66
44
|
}
|
67
|
-
|
68
45
|
function saveOutputToFile(result, options) {
|
69
46
|
if (!options.output) {
|
70
47
|
return;
|
71
48
|
}
|
72
|
-
|
73
49
|
const output = result.output;
|
74
50
|
const filename = options.output.filename;
|
75
|
-
|
76
51
|
if (output && filename) {
|
77
52
|
try {
|
78
|
-
const dir =
|
79
|
-
|
80
|
-
|
81
|
-
recursive: true,
|
82
|
-
});
|
83
|
-
|
84
|
-
_fs.default.writeFileSync(filename, output);
|
53
|
+
const dir = path_1.default.dirname(filename);
|
54
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
55
|
+
fs_1.default.writeFileSync(filename, output);
|
85
56
|
} catch (error) {
|
86
|
-
throw new
|
87
|
-
{
|
88
|
-
code: 'CannotSaveFile',
|
89
|
-
},
|
90
|
-
error
|
91
|
-
);
|
57
|
+
throw new app_error_1.AppError({ code: 'CannotSaveFile' }, error);
|
92
58
|
}
|
93
59
|
}
|
94
60
|
}
|
61
|
+
exports.saveOutputToFile = saveOutputToFile;
|
62
|
+
//# sourceMappingURL=output.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":";;;;;AAAA,4CAAoB;AACpB,gDAAwB;AACxB,4CAAoB;AAEpB,iCAAsC;AACtC,2CAAuC;AAIvC,SAAgB,YAAY,CAC1B,OAA8B,EAC9B,OAAuB;IAEvB,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;QACnB,OAAO;KACR;IAED,QAAQ,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE;QAC7B,KAAK,MAAM;YACT,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAEjD,KAAK,KAAK;YACR,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;QAE9B,KAAK,MAAM;YACT,OAAO,mBAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;KACzC;AACH,CAAC;AAlBD,oCAkBC;AAED,SAAS,WAAW,CAAC,OAA8B;IACjD,MAAM,KAAK,GAAG,CAAC,cAAc,CAAC,CAAC;IAE/B,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QAChC,IAAI,KAAK,GAAG,CAAC,EAAE;YAEb,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SAChB;QAED,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;aACzB,GAAG,CAAmB,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;aAC9D,IAAI,CAAC,eAAe,CAAC;aACrB,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;YAC1B,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC,IAAI,CAAC,YAAE,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,eAAe,CAAC,CAAC,EAAE,KAAK,CAAmB,EAAE,CAAC,EAAE,KAAK,CAAmB;IAC/E,OAAO,KAAK,GAAG,KAAK,CAAC;AACvB,CAAC;AAED,SAAgB,gBAAgB,CAAC,MAAqB,EAAE,OAAuB;IAC7E,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;QACnB,OAAO;KACR;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;IAEzC,IAAI,MAAM,IAAI,QAAQ,EAAE;QACtB,IAAI;YACF,MAAM,GAAG,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAEnC,YAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACvC,YAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;SACpC;QAAC,OAAO,KAAK,EAAE;YACd,MAAM,IAAI,oBAAQ,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,KAAK,CAAC,CAAC;SACvD;KACF;AACH,CAAC;AAlBD,4CAkBC","sourcesContent":["import os from 'os';\nimport path from 'path';\nimport fs from 'fs';\n\nimport { generateHtml } from './html';\nimport { AppError } from './app-error';\n\nimport type { ExploreBundleResult, ExploreOptions, ExploreResult } from './types';\n\nexport function formatOutput(\n results: ExploreBundleResult[],\n options: ExploreOptions\n): string | undefined {\n if (!options.output) {\n return;\n }\n\n switch (options.output.format) {\n case 'json':\n return JSON.stringify({ results }, null, ' ');\n\n case 'tsv':\n return outputAsTsv(results);\n\n case 'html':\n return generateHtml(results, options);\n }\n}\n\nfunction outputAsTsv(results: ExploreBundleResult[]): string {\n const lines = ['Source\\tSize'];\n\n results.forEach((bundle, index) => {\n if (index > 0) {\n // Separate bundles by empty line\n lines.push('');\n }\n\n Object.entries(bundle.files)\n .map<[string, number]>(([source, data]) => [source, data.size])\n .sort(sortFilesBySize)\n .forEach(([source, size]) => {\n lines.push(`${source}\\t${size}`);\n });\n });\n\n return lines.join(os.EOL);\n}\n\nfunction sortFilesBySize([, aSize]: [string, number], [, bSize]: [string, number]): number {\n return bSize - aSize;\n}\n\nexport function saveOutputToFile(result: ExploreResult, options: ExploreOptions): void {\n if (!options.output) {\n return;\n }\n\n const output = result.output;\n const filename = options.output.filename;\n\n if (output && filename) {\n try {\n const dir = path.dirname(filename);\n\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(filename, output);\n } catch (error) {\n throw new AppError({ code: 'CannotSaveFile' }, error);\n }\n }\n}\n"]}
|