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/explore.js
CHANGED
@@ -1,125 +1,114 @@
|
|
1
1
|
'use strict';
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
}
|
6
|
-
|
7
|
-
exports
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
function _interopRequireDefault(obj) {
|
29
|
-
return obj && obj.__esModule ? obj : { default: obj };
|
30
|
-
}
|
31
|
-
|
32
|
-
const UNMAPPED_KEY = '[unmapped]';
|
33
|
-
exports.UNMAPPED_KEY = UNMAPPED_KEY;
|
34
|
-
const SOURCE_MAP_COMMENT_KEY = '[sourceMappingURL]';
|
35
|
-
exports.SOURCE_MAP_COMMENT_KEY = SOURCE_MAP_COMMENT_KEY;
|
36
|
-
const NO_SOURCE_KEY = '[no source]';
|
37
|
-
exports.NO_SOURCE_KEY = NO_SOURCE_KEY;
|
38
|
-
const EOL_KEY = '[EOLs]';
|
39
|
-
exports.EOL_KEY = EOL_KEY;
|
40
|
-
const SPECIAL_FILENAMES = [UNMAPPED_KEY, SOURCE_MAP_COMMENT_KEY, NO_SOURCE_KEY, EOL_KEY];
|
41
|
-
/**
|
42
|
-
* Analyze a bundle
|
43
|
-
*/
|
44
|
-
|
45
|
-
exports.SPECIAL_FILENAMES = SPECIAL_FILENAMES;
|
46
|
-
|
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 convert_source_map_1 = __importDefault(require('convert-source-map'));
|
9
|
+
const path_1 = __importDefault(require('path'));
|
10
|
+
const source_map_1 = require('source-map');
|
11
|
+
const gzip_size_1 = __importDefault(require('gzip-size'));
|
12
|
+
const lodash_1 = require('lodash');
|
13
|
+
const api_1 = require('./api');
|
14
|
+
const helpers_1 = require('./helpers');
|
15
|
+
const app_error_1 = require('./app-error');
|
16
|
+
const coverage_1 = require('./coverage');
|
17
|
+
exports.UNMAPPED_KEY = '[unmapped]';
|
18
|
+
exports.SOURCE_MAP_COMMENT_KEY = '[sourceMappingURL]';
|
19
|
+
exports.NO_SOURCE_KEY = '[no source]';
|
20
|
+
exports.EOL_KEY = '[EOLs]';
|
21
|
+
exports.SPECIAL_FILENAMES = [
|
22
|
+
exports.UNMAPPED_KEY,
|
23
|
+
exports.SOURCE_MAP_COMMENT_KEY,
|
24
|
+
exports.NO_SOURCE_KEY,
|
25
|
+
exports.EOL_KEY,
|
26
|
+
];
|
47
27
|
async function exploreBundle(bundle, options) {
|
48
28
|
const { code, map, coverageRanges } = bundle;
|
49
29
|
const sourceMapData = await loadSourceMap(code, map);
|
50
30
|
const sizes = computeFileSizes(sourceMapData, options, coverageRanges);
|
51
|
-
const files = adjustSourcePaths(sizes.files, options);
|
52
|
-
|
31
|
+
const files = adjustSourcePaths(sizes.files, options);
|
53
32
|
sourceMapData.consumer.destroy();
|
54
33
|
return {
|
55
|
-
bundleName:
|
34
|
+
bundleName: api_1.getBundleName(bundle),
|
56
35
|
...sizes,
|
57
36
|
files,
|
58
37
|
};
|
59
38
|
}
|
60
|
-
|
61
|
-
/**
|
62
|
-
* Get source map
|
63
|
-
*/
|
39
|
+
exports.exploreBundle = exploreBundle;
|
64
40
|
async function loadSourceMap(codeFile, sourceMapFile) {
|
65
|
-
const codeFileContent =
|
41
|
+
const codeFileContent = helpers_1.getFileContent(codeFile);
|
66
42
|
let consumer;
|
67
|
-
|
68
43
|
if (sourceMapFile) {
|
69
|
-
const sourceMapFileContent =
|
70
|
-
consumer = await new
|
44
|
+
const sourceMapFileContent = helpers_1.getFileContent(sourceMapFile);
|
45
|
+
consumer = await new source_map_1.SourceMapConsumer(sourceMapFileContent);
|
71
46
|
} else {
|
72
|
-
|
73
|
-
let converter = _convertSourceMap.default.fromSource(codeFileContent);
|
74
|
-
|
47
|
+
let converter = convert_source_map_1.default.fromSource(codeFileContent);
|
75
48
|
if (!converter && !Buffer.isBuffer(codeFile)) {
|
76
|
-
converter =
|
49
|
+
converter = convert_source_map_1.default.fromMapFileSource(
|
77
50
|
codeFileContent,
|
78
|
-
|
51
|
+
path_1.default.dirname(codeFile)
|
79
52
|
);
|
80
53
|
}
|
81
|
-
|
82
54
|
if (!converter) {
|
83
|
-
throw new
|
84
|
-
code: 'NoSourceMap',
|
85
|
-
});
|
55
|
+
throw new app_error_1.AppError({ code: 'NoSourceMap' });
|
86
56
|
}
|
87
|
-
|
88
|
-
consumer = await new _sourceMap.SourceMapConsumer(converter.toJSON());
|
57
|
+
consumer = await new source_map_1.SourceMapConsumer(converter.toJSON());
|
89
58
|
}
|
90
|
-
|
91
59
|
if (!consumer) {
|
92
|
-
throw new
|
93
|
-
code: 'NoSourceMap',
|
94
|
-
});
|
60
|
+
throw new app_error_1.AppError({ code: 'NoSourceMap' });
|
95
61
|
}
|
96
|
-
|
97
62
|
return {
|
98
63
|
consumer,
|
99
64
|
codeFileContent,
|
100
65
|
};
|
101
66
|
}
|
102
|
-
|
103
|
-
const
|
104
|
-
const MAP_FILE_COMMENT_REGEX = _convertSourceMap.default.mapFileCommentRegex;
|
105
|
-
/**
|
106
|
-
* Extract either source map comment/file
|
107
|
-
*/
|
108
|
-
|
67
|
+
const COMMENT_REGEX = convert_source_map_1.default.commentRegex;
|
68
|
+
const MAP_FILE_COMMENT_REGEX = convert_source_map_1.default.mapFileCommentRegex;
|
109
69
|
function getSourceMapComment(fileContent) {
|
110
70
|
const sourceMapComment =
|
111
|
-
|
112
|
-
|
113
|
-
'';
|
114
|
-
|
71
|
+
helpers_1.getFirstRegexMatch(COMMENT_REGEX, fileContent) ||
|
72
|
+
helpers_1.getFirstRegexMatch(MAP_FILE_COMMENT_REGEX, fileContent) ||
|
73
|
+
'';
|
115
74
|
return sourceMapComment.trim();
|
116
75
|
}
|
117
|
-
|
118
|
-
|
76
|
+
function isReferencingEOL(context, maxColumnIndex) {
|
77
|
+
const { generatedLine, generatedColumn, source, consumer } = context;
|
78
|
+
if (maxColumnIndex - generatedColumn > 2) {
|
79
|
+
return false;
|
80
|
+
}
|
81
|
+
if (!source) {
|
82
|
+
return false;
|
83
|
+
}
|
84
|
+
if (context.mapReferenceEOLSources.has(source)) {
|
85
|
+
return true;
|
86
|
+
}
|
87
|
+
const content = consumer.sourceContentFor(source, true);
|
88
|
+
if (!content) {
|
89
|
+
return false;
|
90
|
+
}
|
91
|
+
const { line, column } = consumer.originalPositionFor({
|
92
|
+
line: generatedLine,
|
93
|
+
column: generatedColumn,
|
94
|
+
});
|
95
|
+
if (line === null || column === null) {
|
96
|
+
return false;
|
97
|
+
}
|
98
|
+
if (helpers_1.isEOLAtPosition(content, [line, column])) {
|
99
|
+
context.mapReferenceEOLSources.add(source);
|
100
|
+
return true;
|
101
|
+
}
|
102
|
+
return false;
|
103
|
+
}
|
104
|
+
function checkInvalidMappingColumn(context) {
|
105
|
+
const { line, generatedLine, generatedColumn } = context;
|
119
106
|
const maxColumnIndex = line.length - 1;
|
120
|
-
|
121
107
|
if (generatedColumn > maxColumnIndex) {
|
122
|
-
|
108
|
+
if (isReferencingEOL(context, maxColumnIndex)) {
|
109
|
+
return;
|
110
|
+
}
|
111
|
+
throw new app_error_1.AppError({
|
123
112
|
code: 'InvalidMappingColumn',
|
124
113
|
generatedLine,
|
125
114
|
generatedColumn,
|
@@ -127,132 +116,111 @@ function checkInvalidMappingColumn({ generatedLine, generatedColumn, line }) {
|
|
127
116
|
});
|
128
117
|
}
|
129
118
|
}
|
130
|
-
/**
|
131
|
-
* Calculate the number of bytes contributed by each source file
|
132
|
-
*/
|
133
|
-
|
134
119
|
function computeFileSizes(sourceMapData, options, coverageRanges) {
|
135
120
|
const { consumer, codeFileContent: fileContent } = sourceMapData;
|
136
|
-
const sourceMapComment = getSourceMapComment(fileContent);
|
137
|
-
|
138
|
-
const
|
139
|
-
const
|
140
|
-
|
141
|
-
const lines = source.split(eol);
|
121
|
+
const sourceMapComment = getSourceMapComment(fileContent);
|
122
|
+
const sourceContent = fileContent.replace(sourceMapComment, '').trim();
|
123
|
+
const eol = helpers_1.detectEOL(fileContent);
|
124
|
+
const lines = sourceContent.split(eol);
|
142
125
|
const mappingRanges = [];
|
126
|
+
const context = {
|
127
|
+
generatedLine: -1,
|
128
|
+
generatedColumn: -1,
|
129
|
+
line: '',
|
130
|
+
source: null,
|
131
|
+
consumer,
|
132
|
+
mapReferenceEOLSources: new Set(),
|
133
|
+
};
|
143
134
|
consumer.computeColumnSpans();
|
144
135
|
consumer.eachMapping(({ source, generatedLine, generatedColumn, lastGeneratedColumn }) => {
|
145
|
-
// Columns are 0-based, Lines are 1-based
|
146
136
|
const lineIndex = generatedLine - 1;
|
147
137
|
const line = lines[lineIndex];
|
148
|
-
|
149
138
|
if (line === undefined) {
|
150
|
-
|
139
|
+
if (options.noBorderChecks) {
|
140
|
+
return;
|
141
|
+
}
|
142
|
+
throw new app_error_1.AppError({
|
151
143
|
code: 'InvalidMappingLine',
|
152
144
|
generatedLine,
|
153
145
|
maxLine: lines.length,
|
154
146
|
});
|
155
|
-
}
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
147
|
+
}
|
148
|
+
context.generatedLine = generatedLine;
|
149
|
+
context.generatedColumn = lastGeneratedColumn || generatedColumn;
|
150
|
+
context.line = line;
|
151
|
+
context.source = source;
|
152
|
+
if (!options.noBorderChecks) {
|
153
|
+
checkInvalidMappingColumn(context);
|
154
|
+
}
|
163
155
|
const start = generatedColumn;
|
164
156
|
const end = lastGeneratedColumn === null ? line.length - 1 : lastGeneratedColumn;
|
165
157
|
const lineRanges = mappingRanges[lineIndex] || [];
|
166
158
|
lineRanges.push({
|
167
159
|
start,
|
168
160
|
end,
|
169
|
-
source: source === null ? NO_SOURCE_KEY : source,
|
161
|
+
source: source === null ? exports.NO_SOURCE_KEY : source,
|
170
162
|
});
|
171
163
|
mappingRanges[lineIndex] = lineRanges;
|
172
164
|
});
|
173
165
|
let files = {};
|
174
166
|
let mappedBytes = 0;
|
175
|
-
const getSize = options.gzip ?
|
167
|
+
const getSize = options.gzip ? gzip_size_1.default.sync : Buffer.byteLength;
|
176
168
|
mappingRanges.forEach((lineRanges, lineIndex) => {
|
177
169
|
const line = lines[lineIndex];
|
178
|
-
const mergedRanges =
|
170
|
+
const mergedRanges = helpers_1.mergeRanges(lineRanges);
|
179
171
|
mergedRanges.forEach(({ start, end, source }) => {
|
180
|
-
const rangeString = line.substring(start, end + 1);
|
181
|
-
|
172
|
+
const rangeString = line.substring(start, end + 1);
|
182
173
|
const rangeByteLength = getSize(rangeString);
|
183
|
-
|
184
174
|
if (!files[source]) {
|
185
|
-
files[source] = {
|
186
|
-
size: 0,
|
187
|
-
};
|
175
|
+
files[source] = { size: 0 };
|
188
176
|
}
|
189
|
-
|
190
177
|
files[source].size += rangeByteLength;
|
191
178
|
mappedBytes += rangeByteLength;
|
192
179
|
});
|
193
|
-
|
194
180
|
if (coverageRanges) {
|
195
|
-
files =
|
181
|
+
files = coverage_1.setCoveredSizes(line, files, mergedRanges, coverageRanges[lineIndex]);
|
196
182
|
}
|
197
183
|
});
|
198
184
|
const sourceMapCommentBytes = getSize(sourceMapComment);
|
199
|
-
const eolBytes =
|
185
|
+
const eolBytes = helpers_1.getOccurrencesCount(eol, fileContent) * Buffer.byteLength(eol);
|
200
186
|
const totalBytes = getSize(fileContent);
|
201
187
|
let unmappedBytes;
|
202
|
-
|
203
188
|
if (!options.excludeSourceMapComment) {
|
204
|
-
files[SOURCE_MAP_COMMENT_KEY] = {
|
205
|
-
size: sourceMapCommentBytes,
|
206
|
-
};
|
189
|
+
files[exports.SOURCE_MAP_COMMENT_KEY] = { size: sourceMapCommentBytes };
|
207
190
|
}
|
208
|
-
|
209
191
|
if (!options.onlyMapped) {
|
210
192
|
unmappedBytes = totalBytes - mappedBytes - sourceMapCommentBytes - eolBytes;
|
211
|
-
files[UNMAPPED_KEY] = {
|
212
|
-
size: unmappedBytes,
|
213
|
-
};
|
193
|
+
files[exports.UNMAPPED_KEY] = { size: unmappedBytes };
|
214
194
|
}
|
215
|
-
|
216
195
|
if (eolBytes > 0) {
|
217
|
-
files[EOL_KEY] = {
|
218
|
-
size: eolBytes,
|
219
|
-
};
|
196
|
+
files[exports.EOL_KEY] = { size: eolBytes };
|
220
197
|
}
|
221
|
-
|
222
198
|
return {
|
223
199
|
...(options.excludeSourceMapComment
|
224
|
-
? {
|
225
|
-
|
226
|
-
}
|
227
|
-
: {
|
228
|
-
totalBytes,
|
229
|
-
}),
|
200
|
+
? { totalBytes: totalBytes - sourceMapCommentBytes }
|
201
|
+
: { totalBytes }),
|
230
202
|
mappedBytes,
|
231
|
-
...(!options.onlyMapped && {
|
232
|
-
unmappedBytes,
|
233
|
-
}),
|
203
|
+
...(!options.onlyMapped && { unmappedBytes }),
|
234
204
|
eolBytes,
|
235
205
|
sourceMapCommentBytes,
|
236
206
|
files,
|
237
207
|
};
|
238
208
|
}
|
239
|
-
|
240
209
|
function adjustSourcePaths(fileSizeMap, options) {
|
241
210
|
if (!options.noRoot) {
|
242
|
-
const prefix =
|
211
|
+
const prefix = helpers_1.getCommonPathPrefix(Object.keys(fileSizeMap));
|
243
212
|
const length = prefix.length;
|
244
|
-
|
245
213
|
if (length) {
|
246
|
-
fileSizeMap =
|
214
|
+
fileSizeMap = lodash_1.mapKeys(fileSizeMap, (size, source) => source.slice(length));
|
247
215
|
}
|
248
216
|
}
|
249
|
-
|
250
217
|
if (options.replaceMap) {
|
251
218
|
fileSizeMap = Object.entries(options.replaceMap).reduce((result, [before, after]) => {
|
252
219
|
const regexp = new RegExp(before, 'g');
|
253
|
-
return
|
220
|
+
return lodash_1.mapKeys(result, (size, source) => source.replace(regexp, after));
|
254
221
|
}, fileSizeMap);
|
255
222
|
}
|
256
|
-
|
257
223
|
return fileSizeMap;
|
258
224
|
}
|
225
|
+
exports.adjustSourcePaths = adjustSourcePaths;
|
226
|
+
//# sourceMappingURL=explore.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"explore.js","sourceRoot":"","sources":["../src/explore.ts"],"names":[],"mappings":"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","sourcesContent":["import convert from 'convert-source-map';\nimport path from 'path';\nimport { BasicSourceMapConsumer, IndexedSourceMapConsumer, SourceMapConsumer } from 'source-map';\nimport gzipSize from 'gzip-size';\nimport { mapKeys } from 'lodash';\n\nimport { getBundleName } from './api';\nimport {\n getFileContent,\n getCommonPathPrefix,\n getFirstRegexMatch,\n detectEOL,\n getOccurrencesCount,\n isEOLAtPosition,\n mergeRanges,\n} from './helpers';\nimport { AppError } from './app-error';\nimport { setCoveredSizes } from './coverage';\n\nimport type {\n Bundle,\n CoverageRange,\n ExploreBundleResult,\n ExploreOptions,\n File,\n FileDataMap,\n FileSizes,\n MappingRange,\n} from './types';\n\nexport const UNMAPPED_KEY = '[unmapped]';\nexport const SOURCE_MAP_COMMENT_KEY = '[sourceMappingURL]';\nexport const NO_SOURCE_KEY = '[no source]';\nexport const EOL_KEY = '[EOLs]';\n\nexport const SPECIAL_FILENAMES = [UNMAPPED_KEY, SOURCE_MAP_COMMENT_KEY, NO_SOURCE_KEY, EOL_KEY];\n\n/**\n * Analyze a bundle\n */\nexport async function exploreBundle(\n bundle: Bundle,\n options: ExploreOptions\n): Promise<ExploreBundleResult> {\n const { code, map, coverageRanges } = bundle;\n\n const sourceMapData = await loadSourceMap(code, map);\n\n const sizes = computeFileSizes(sourceMapData, options, coverageRanges);\n\n const files = adjustSourcePaths(sizes.files, options);\n\n // Free Wasm data\n sourceMapData.consumer.destroy();\n\n return {\n bundleName: getBundleName(bundle),\n ...sizes,\n files,\n };\n}\n\ntype Consumer = BasicSourceMapConsumer | IndexedSourceMapConsumer;\n\ninterface SourceMapData {\n consumer: Consumer;\n codeFileContent: string;\n}\n\n/**\n * Get source map\n */\nasync function loadSourceMap(codeFile: File, sourceMapFile?: File): Promise<SourceMapData> {\n const codeFileContent = getFileContent(codeFile);\n\n let consumer: Consumer;\n\n if (sourceMapFile) {\n const sourceMapFileContent = getFileContent(sourceMapFile);\n\n consumer = await new SourceMapConsumer(sourceMapFileContent);\n } else {\n // Try to read a source map from a 'sourceMappingURL' comment.\n let converter = convert.fromSource(codeFileContent);\n\n if (!converter && !Buffer.isBuffer(codeFile)) {\n converter = convert.fromMapFileSource(codeFileContent, path.dirname(codeFile));\n }\n\n if (!converter) {\n throw new AppError({ code: 'NoSourceMap' });\n }\n\n consumer = await new SourceMapConsumer(converter.toJSON());\n }\n\n if (!consumer) {\n throw new AppError({ code: 'NoSourceMap' });\n }\n\n return {\n consumer,\n codeFileContent,\n };\n}\n\nconst COMMENT_REGEX = convert.commentRegex;\nconst MAP_FILE_COMMENT_REGEX = convert.mapFileCommentRegex;\n\n/**\n * Extract either source map comment/file\n */\nfunction getSourceMapComment(fileContent: string): string {\n const sourceMapComment =\n getFirstRegexMatch(COMMENT_REGEX, fileContent) ||\n getFirstRegexMatch(MAP_FILE_COMMENT_REGEX, fileContent) ||\n '';\n\n // Remove trailing EOLs\n return sourceMapComment.trim();\n}\n\ninterface ComputeFileSizesContext {\n generatedLine: number;\n generatedColumn: number;\n line: string;\n source: string | null;\n consumer: Consumer;\n mapReferenceEOLSources: Set<string>;\n}\n\n/**\n * Check if source map references EOL (see https://github.com/microsoft/TypeScript/issues/34695)\n */\nfunction isReferencingEOL(context: ComputeFileSizesContext, maxColumnIndex: number): boolean {\n const { generatedLine, generatedColumn, source, consumer } = context;\n\n // Ignore difference more than EOL max length (\\r\\n)\n if (maxColumnIndex - generatedColumn > 2) {\n return false;\n }\n\n // Ignore mapping w/o source\n if (!source) {\n return false;\n }\n\n // Don't check the same source twice. It covers most cases even though not 100% reliable\n if (context.mapReferenceEOLSources.has(source)) {\n return true;\n }\n\n const content = consumer.sourceContentFor(source, true);\n\n // Content is needed to detect EOL\n if (!content) {\n return false;\n }\n\n const { line, column } = consumer.originalPositionFor({\n line: generatedLine,\n column: generatedColumn,\n });\n\n if (line === null || column === null) {\n return false;\n }\n\n if (isEOLAtPosition(content, [line, column])) {\n context.mapReferenceEOLSources.add(source);\n\n return true;\n }\n\n return false;\n}\n\nfunction checkInvalidMappingColumn(context: ComputeFileSizesContext): void {\n const { line, generatedLine, generatedColumn } = context;\n const maxColumnIndex = line.length - 1;\n\n if (generatedColumn > maxColumnIndex) {\n if (isReferencingEOL(context, maxColumnIndex)) {\n return;\n }\n\n throw new AppError({\n code: 'InvalidMappingColumn',\n generatedLine,\n generatedColumn,\n maxColumn: line.length,\n });\n }\n}\n\n/**\n * Calculate the number of bytes contributed by each source file\n */\nfunction computeFileSizes(\n sourceMapData: SourceMapData,\n options: ExploreOptions,\n coverageRanges?: CoverageRange[][]\n): FileSizes {\n const { consumer, codeFileContent: fileContent } = sourceMapData;\n\n const sourceMapComment = getSourceMapComment(fileContent);\n // Remove inline source map comment, source map file comment and trailing EOLs\n const sourceContent = fileContent.replace(sourceMapComment, '').trim();\n\n const eol = detectEOL(fileContent);\n // Assume only one type of EOL is used\n const lines = sourceContent.split(eol);\n\n const mappingRanges: MappingRange[][] = [];\n\n const context: ComputeFileSizesContext = {\n generatedLine: -1,\n generatedColumn: -1,\n line: '',\n source: null,\n consumer,\n mapReferenceEOLSources: new Set(),\n };\n\n consumer.computeColumnSpans();\n consumer.eachMapping(({ source, generatedLine, generatedColumn, lastGeneratedColumn }) => {\n // Columns are 0-based, Lines are 1-based\n\n const lineIndex = generatedLine - 1;\n const line = lines[lineIndex];\n\n if (line === undefined) {\n if (options.noBorderChecks) {\n return;\n }\n\n throw new AppError({\n code: 'InvalidMappingLine',\n generatedLine,\n maxLine: lines.length,\n });\n }\n\n context.generatedLine = generatedLine;\n context.generatedColumn = lastGeneratedColumn || generatedColumn;\n context.line = line;\n context.source = source;\n\n if (!options.noBorderChecks) {\n checkInvalidMappingColumn(context);\n }\n\n const start = generatedColumn;\n const end = lastGeneratedColumn === null ? line.length - 1 : lastGeneratedColumn;\n\n const lineRanges = mappingRanges[lineIndex] || [];\n\n lineRanges.push({\n start,\n end,\n source: source === null ? NO_SOURCE_KEY : source,\n });\n\n mappingRanges[lineIndex] = lineRanges;\n });\n\n let files: FileDataMap = {};\n let mappedBytes = 0;\n\n // To account unicode measure byte length rather than symbols count\n const getSize = options.gzip ? gzipSize.sync : Buffer.byteLength;\n\n mappingRanges.forEach((lineRanges, lineIndex) => {\n const line = lines[lineIndex];\n const mergedRanges = mergeRanges(lineRanges);\n\n mergedRanges.forEach(({ start, end, source }) => {\n const rangeString = line.substring(start, end + 1);\n const rangeByteLength = getSize(rangeString);\n\n if (!files[source]) {\n files[source] = { size: 0 };\n }\n\n files[source].size += rangeByteLength;\n\n mappedBytes += rangeByteLength;\n });\n\n if (coverageRanges) {\n files = setCoveredSizes(line, files, mergedRanges, coverageRanges[lineIndex]);\n }\n });\n\n const sourceMapCommentBytes = getSize(sourceMapComment);\n const eolBytes = getOccurrencesCount(eol, fileContent) * Buffer.byteLength(eol);\n const totalBytes = getSize(fileContent);\n let unmappedBytes: number | undefined;\n\n if (!options.excludeSourceMapComment) {\n files[SOURCE_MAP_COMMENT_KEY] = { size: sourceMapCommentBytes };\n }\n\n if (!options.onlyMapped) {\n unmappedBytes = totalBytes - mappedBytes - sourceMapCommentBytes - eolBytes;\n files[UNMAPPED_KEY] = { size: unmappedBytes };\n }\n\n if (eolBytes > 0) {\n files[EOL_KEY] = { size: eolBytes };\n }\n\n return {\n ...(options.excludeSourceMapComment\n ? { totalBytes: totalBytes - sourceMapCommentBytes }\n : { totalBytes }),\n mappedBytes,\n ...(!options.onlyMapped && { unmappedBytes }),\n eolBytes,\n sourceMapCommentBytes,\n files,\n };\n}\n\nexport function adjustSourcePaths(fileSizeMap: FileDataMap, options: ExploreOptions): FileDataMap {\n if (!options.noRoot) {\n const prefix = getCommonPathPrefix(Object.keys(fileSizeMap));\n const length = prefix.length;\n\n if (length) {\n fileSizeMap = mapKeys(fileSizeMap, (size, source) => source.slice(length));\n }\n }\n\n if (options.replaceMap) {\n fileSizeMap = Object.entries(options.replaceMap).reduce((result, [before, after]) => {\n const regexp = new RegExp(before, 'g');\n\n return mapKeys(result, (size, source) => source.replace(regexp, after));\n }, fileSizeMap);\n }\n\n return fileSizeMap;\n}\n"]}
|
package/dist/helpers.d.ts
CHANGED
@@ -1,25 +1,11 @@
|
|
1
1
|
/// <reference types="node" />
|
2
|
-
import { MappingRange } from './
|
2
|
+
import type { MappingRange } from './types';
|
3
3
|
export declare function getFileContent(file: Buffer | string): string;
|
4
|
-
/**
|
5
|
-
* Format number of bytes as string
|
6
|
-
* Source @see https://stackoverflow.com/a/18650828/388951
|
7
|
-
*/
|
8
4
|
export declare function formatBytes(bytes: number, decimals?: number): string;
|
9
5
|
export declare function formatPercent(value: number, total: number, fractionDigits?: number): string;
|
10
|
-
/**
|
11
|
-
* Find common path prefix
|
12
|
-
* Source @see http://stackoverflow.com/a/1917041/388951
|
13
|
-
* @param paths List of filenames
|
14
|
-
*/
|
15
6
|
export declare function getCommonPathPrefix(paths: string[]): string;
|
16
7
|
export declare function getFirstRegexMatch(regex: RegExp, string: string): string | null;
|
17
8
|
export declare function detectEOL(content: string): string;
|
18
|
-
/**
|
19
|
-
* Get `subString` occurrences count in `string`
|
20
|
-
*/
|
21
9
|
export declare function getOccurrencesCount(subString: string, string: string): number;
|
22
|
-
|
23
|
-
* Merge consecutive ranges with the same source
|
24
|
-
*/
|
10
|
+
export declare function isEOLAtPosition(string: string, [line, column]: [number, number]): boolean;
|
25
11
|
export declare function mergeRanges(ranges: MappingRange[]): MappingRange[];
|
package/dist/helpers.js
CHANGED
@@ -1,55 +1,30 @@
|
|
1
1
|
'use strict';
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
}
|
6
|
-
|
7
|
-
exports
|
8
|
-
|
9
|
-
exports.getCommonPathPrefix = getCommonPathPrefix;
|
10
|
-
exports.getFirstRegexMatch = getFirstRegexMatch;
|
11
|
-
exports.detectEOL = detectEOL;
|
12
|
-
exports.getOccurrencesCount = getOccurrencesCount;
|
13
|
-
exports.mergeRanges = mergeRanges;
|
14
|
-
|
15
|
-
var _fs = _interopRequireDefault(require('fs'));
|
16
|
-
|
17
|
-
function _interopRequireDefault(obj) {
|
18
|
-
return obj && obj.__esModule ? obj : { default: obj };
|
19
|
-
}
|
20
|
-
|
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 fs_1 = __importDefault(require('fs'));
|
21
9
|
function getFileContent(file) {
|
22
|
-
const buffer = Buffer.isBuffer(file) ? file :
|
10
|
+
const buffer = Buffer.isBuffer(file) ? file : fs_1.default.readFileSync(file);
|
23
11
|
return buffer.toString();
|
24
12
|
}
|
25
|
-
|
26
|
-
const BYTE_SIZES = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
27
|
-
|
13
|
+
exports.getFileContent = getFileContent;
|
14
|
+
const BYTE_SIZES = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
28
15
|
const SIZE_BASE = 1024;
|
29
|
-
/**
|
30
|
-
* Format number of bytes as string
|
31
|
-
* Source @see https://stackoverflow.com/a/18650828/388951
|
32
|
-
*/
|
33
|
-
|
34
16
|
function formatBytes(bytes, decimals = 2) {
|
35
17
|
if (bytes === 0) return `0 ${BYTE_SIZES[0]}`;
|
36
18
|
const exponent = Math.floor(Math.log(bytes) / Math.log(SIZE_BASE));
|
37
|
-
const value = bytes / Math.pow(SIZE_BASE, exponent);
|
38
|
-
|
19
|
+
const value = bytes / Math.pow(SIZE_BASE, exponent);
|
39
20
|
return `${parseFloat(value.toFixed(decimals))} ${BYTE_SIZES[exponent]}`;
|
40
21
|
}
|
41
|
-
|
22
|
+
exports.formatBytes = formatBytes;
|
42
23
|
function formatPercent(value, total, fractionDigits) {
|
43
24
|
return ((100.0 * value) / total).toFixed(fractionDigits);
|
44
25
|
}
|
45
|
-
|
26
|
+
exports.formatPercent = formatPercent;
|
46
27
|
const PATH_SEPARATOR_REGEX = /(\/)/;
|
47
|
-
/**
|
48
|
-
* Find common path prefix
|
49
|
-
* Source @see http://stackoverflow.com/a/1917041/388951
|
50
|
-
* @param paths List of filenames
|
51
|
-
*/
|
52
|
-
|
53
28
|
function getCommonPathPrefix(paths) {
|
54
29
|
if (paths.length < 2) return '';
|
55
30
|
const A = paths.concat().sort();
|
@@ -57,73 +32,65 @@ function getCommonPathPrefix(paths) {
|
|
57
32
|
const a2 = A[A.length - 1].split(PATH_SEPARATOR_REGEX);
|
58
33
|
const L = a1.length;
|
59
34
|
let i = 0;
|
60
|
-
|
61
35
|
while (i < L && a1[i] === a2[i]) i++;
|
62
|
-
|
63
36
|
return a1.slice(0, i).join('');
|
64
37
|
}
|
65
|
-
|
38
|
+
exports.getCommonPathPrefix = getCommonPathPrefix;
|
66
39
|
function getFirstRegexMatch(regex, string) {
|
67
40
|
const match = string.match(regex);
|
68
41
|
return match ? match[0] : null;
|
69
42
|
}
|
70
|
-
|
43
|
+
exports.getFirstRegexMatch = getFirstRegexMatch;
|
71
44
|
const LF = '\n';
|
72
45
|
const CR_LF = '\r\n';
|
73
|
-
|
74
46
|
function detectEOL(content) {
|
75
47
|
return content.includes(CR_LF) ? CR_LF : LF;
|
76
48
|
}
|
77
|
-
|
78
|
-
* Get `subString` occurrences count in `string`
|
79
|
-
*/
|
80
|
-
|
49
|
+
exports.detectEOL = detectEOL;
|
81
50
|
function getOccurrencesCount(subString, string) {
|
82
51
|
let count = 0;
|
83
52
|
let position = string.indexOf(subString);
|
84
53
|
const subStringLength = subString.length;
|
85
|
-
|
86
54
|
while (position !== -1) {
|
87
55
|
count += 1;
|
88
56
|
position = string.indexOf(subString, position + subStringLength);
|
89
57
|
}
|
90
|
-
|
91
58
|
return count;
|
92
59
|
}
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
60
|
+
exports.getOccurrencesCount = getOccurrencesCount;
|
61
|
+
function isEOLAtPosition(string, [line, column]) {
|
62
|
+
const eol = detectEOL(string);
|
63
|
+
const eolLength = eol.length;
|
64
|
+
let lineOffset = 0;
|
65
|
+
for (let lineIndex = 1; lineIndex < line; lineIndex += 1) {
|
66
|
+
lineOffset = string.indexOf(eol, lineOffset);
|
67
|
+
if (lineOffset === -1) {
|
68
|
+
return false;
|
69
|
+
}
|
70
|
+
lineOffset += eolLength;
|
71
|
+
}
|
72
|
+
return string.substr(lineOffset + column, eolLength) === eol;
|
73
|
+
}
|
74
|
+
exports.isEOLAtPosition = isEOLAtPosition;
|
97
75
|
function mergeRanges(ranges) {
|
98
76
|
const mergedRanges = [];
|
99
77
|
const rangesCount = ranges.length;
|
100
|
-
|
101
78
|
if (rangesCount === 1) {
|
102
79
|
return ranges;
|
103
80
|
}
|
104
|
-
|
105
81
|
let { start, end, source } = ranges[0];
|
106
|
-
|
107
82
|
for (let i = 1; i < rangesCount; i += 1) {
|
108
83
|
const isSourceMatch = ranges[i].source === ranges[i - 1].source;
|
109
84
|
const isConsecutive = ranges[i].start - ranges[i - 1].end === 1;
|
110
|
-
|
111
85
|
if (isSourceMatch && isConsecutive) {
|
112
86
|
end = ranges[i].end;
|
113
87
|
} else {
|
114
|
-
mergedRanges.push({
|
115
|
-
start,
|
116
|
-
end,
|
117
|
-
source,
|
118
|
-
});
|
88
|
+
mergedRanges.push({ start, end, source });
|
119
89
|
({ start, end, source } = ranges[i]);
|
120
90
|
}
|
121
91
|
}
|
122
|
-
|
123
|
-
mergedRanges.push({
|
124
|
-
start,
|
125
|
-
end,
|
126
|
-
source,
|
127
|
-
});
|
92
|
+
mergedRanges.push({ start, end, source });
|
128
93
|
return mergedRanges;
|
129
94
|
}
|
95
|
+
exports.mergeRanges = mergeRanges;
|
96
|
+
//# sourceMappingURL=helpers.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\n\nimport type { MappingRange } from './types';\n\nexport function getFileContent(file: Buffer | string): string {\n const buffer = Buffer.isBuffer(file) ? file : fs.readFileSync(file);\n\n return buffer.toString();\n}\n\nconst BYTE_SIZES = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n// Bytes\nconst SIZE_BASE = 1024;\n\n/**\n * Format number of bytes as string\n * Source @see https://stackoverflow.com/a/18650828/388951\n */\nexport function formatBytes(bytes: number, decimals = 2): string {\n if (bytes === 0) return `0 ${BYTE_SIZES[0]}`;\n\n const exponent = Math.floor(Math.log(bytes) / Math.log(SIZE_BASE));\n const value = bytes / Math.pow(SIZE_BASE, exponent);\n\n // `parseFloat` removes trailing zero\n return `${parseFloat(value.toFixed(decimals))} ${BYTE_SIZES[exponent]}`;\n}\n\nexport function formatPercent(value: number, total: number, fractionDigits?: number): string {\n return ((100.0 * value) / total).toFixed(fractionDigits);\n}\n\nconst PATH_SEPARATOR_REGEX = /(\\/)/;\n\n/**\n * Find common path prefix\n * Source @see http://stackoverflow.com/a/1917041/388951\n * @param paths List of filenames\n */\nexport function getCommonPathPrefix(paths: string[]): string {\n if (paths.length < 2) return '';\n\n const A = paths.concat().sort();\n const a1 = A[0].split(PATH_SEPARATOR_REGEX);\n const a2 = A[A.length - 1].split(PATH_SEPARATOR_REGEX);\n const L = a1.length;\n\n let i = 0;\n\n while (i < L && a1[i] === a2[i]) i++;\n\n return a1.slice(0, i).join('');\n}\n\nexport function getFirstRegexMatch(regex: RegExp, string: string): string | null {\n const match = string.match(regex);\n\n return match ? match[0] : null;\n}\n\nconst LF = '\\n';\nconst CR_LF = '\\r\\n';\n\nexport function detectEOL(content: string): string {\n return content.includes(CR_LF) ? CR_LF : LF;\n}\n\n/**\n * Get `subString` occurrences count in `string`\n */\nexport function getOccurrencesCount(subString: string, string: string): number {\n let count = 0;\n let position = string.indexOf(subString);\n const subStringLength = subString.length;\n\n while (position !== -1) {\n count += 1;\n position = string.indexOf(subString, position + subStringLength);\n }\n\n return count;\n}\n\nexport function isEOLAtPosition(string: string, [line, column]: [number, number]): boolean {\n const eol = detectEOL(string);\n const eolLength = eol.length;\n\n let lineOffset = 0;\n\n for (let lineIndex = 1; lineIndex < line; lineIndex += 1) {\n lineOffset = string.indexOf(eol, lineOffset);\n\n if (lineOffset === -1) {\n return false;\n }\n\n lineOffset += eolLength;\n }\n\n return string.substr(lineOffset + column, eolLength) === eol;\n}\n\n/**\n * Merge consecutive ranges with the same source\n */\nexport function mergeRanges(ranges: MappingRange[]): MappingRange[] {\n const mergedRanges: MappingRange[] = [];\n const rangesCount = ranges.length;\n\n if (rangesCount === 1) {\n return ranges;\n }\n\n let { start, end, source } = ranges[0];\n\n for (let i = 1; i < rangesCount; i += 1) {\n const isSourceMatch = ranges[i].source === ranges[i - 1].source;\n const isConsecutive = ranges[i].start - ranges[i - 1].end === 1;\n\n if (isSourceMatch && isConsecutive) {\n end = ranges[i].end;\n } else {\n mergedRanges.push({ start, end, source });\n\n ({ start, end, source } = ranges[i]);\n }\n }\n\n mergedRanges.push({ start, end, source });\n\n return mergedRanges;\n}\n"]}
|
package/dist/html.d.ts
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
import { ExploreOptions, ExploreBundleResult, FileDataMap } from './
|
2
|
-
/**
|
3
|
-
* Generate HTML file content for specified files
|
4
|
-
*/
|
1
|
+
import type { ExploreOptions, ExploreBundleResult, FileDataMap } from './types';
|
5
2
|
export declare function generateHtml(exploreResults: ExploreBundleResult[], options: ExploreOptions): string;
|
6
3
|
interface WebTreeMapNode {
|
7
4
|
name: string;
|
@@ -12,8 +9,5 @@ interface WebTreeMapNode {
|
|
12
9
|
};
|
13
10
|
children?: WebTreeMapNode[];
|
14
11
|
}
|
15
|
-
/**
|
16
|
-
* Convert file size map to webtreemap data
|
17
|
-
*/
|
18
12
|
export declare function getWebTreeMapData(files: FileDataMap): WebTreeMapNode;
|
19
13
|
export {};
|