monocart-reporter 1.7.1 → 1.7.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 +7 -5
- package/lib/cli.js +1 -1
- package/lib/common.js +2 -3
- package/lib/default/options.js +4 -1
- package/lib/generate-data.js +2 -7
- package/lib/generate-report.js +10 -11
- package/lib/index.d.ts +2 -4
- package/lib/index.js +6 -0
- package/lib/merge-data.js +7 -6
- package/lib/plugins/audit/audit.js +4 -2
- package/lib/plugins/comments.js +2 -3
- package/lib/plugins/coverage/converter/collect-source-maps.js +194 -0
- package/lib/plugins/coverage/converter/converter.js +547 -0
- package/lib/plugins/coverage/converter/decode-mappings.js +49 -0
- package/lib/plugins/coverage/{v8 → converter}/dedupe.js +8 -1
- package/lib/plugins/coverage/converter/find-original-range.js +576 -0
- package/lib/plugins/coverage/converter/info-branch.js +30 -0
- package/lib/plugins/coverage/converter/info-function.js +29 -0
- package/lib/plugins/coverage/converter/info-line.js +20 -0
- package/lib/plugins/coverage/converter/position-mapping.js +183 -0
- package/lib/plugins/coverage/{coverage-utils.js → converter/source-path.js} +26 -42
- package/lib/plugins/coverage/coverage.js +51 -67
- package/lib/plugins/coverage/istanbul/istanbul.js +15 -174
- package/lib/plugins/coverage/v8/v8.js +22 -13
- package/lib/plugins/network/network.js +4 -13
- package/lib/plugins/state/client.js +3 -4
- package/lib/plugins/state/state.js +6 -3
- package/lib/runtime/monocart-code-viewer.js +1 -1
- package/lib/runtime/monocart-coverage.js +13 -14
- package/lib/runtime/monocart-formatter.js +1 -1
- package/lib/runtime/monocart-network.js +1 -1
- package/lib/runtime/monocart-reporter.js +1 -1
- package/lib/runtime/monocart-v8.js +1 -1
- package/lib/runtime/monocart-vendor.js +13 -13
- package/lib/utils/util.js +97 -3
- package/package.json +4 -5
- package/lib/plugins/coverage/v8/position-mapping.js +0 -92
- package/lib/plugins/coverage/v8/source-map.js +0 -451
package/lib/utils/util.js
CHANGED
|
@@ -4,9 +4,12 @@ const path = require('path');
|
|
|
4
4
|
const os = require('os');
|
|
5
5
|
const crypto = require('crypto');
|
|
6
6
|
const EC = require('eight-colors');
|
|
7
|
+
const CG = require('console-grid');
|
|
7
8
|
const Share = require('../platform/share.js');
|
|
8
9
|
const { deflateSync } = require('lz-utils');
|
|
9
10
|
|
|
11
|
+
const assetsName = 'assets';
|
|
12
|
+
|
|
10
13
|
const Util = {
|
|
11
14
|
|
|
12
15
|
root: process.cwd(),
|
|
@@ -116,6 +119,23 @@ const Util = {
|
|
|
116
119
|
return sourcePath;
|
|
117
120
|
},
|
|
118
121
|
|
|
122
|
+
// empty or create dir
|
|
123
|
+
initDir: (dirPath) => {
|
|
124
|
+
if (fs.existsSync(dirPath)) {
|
|
125
|
+
Util.rmSync(dirPath);
|
|
126
|
+
}
|
|
127
|
+
fs.mkdirSync(dirPath, {
|
|
128
|
+
recursive: true
|
|
129
|
+
});
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
initAssetsDir: async (options) => {
|
|
133
|
+
const outputFile = await Util.resolveOutputFile(options.outputFile);
|
|
134
|
+
const outputDir = path.dirname(outputFile);
|
|
135
|
+
const assetsDir = path.resolve(outputDir, assetsName);
|
|
136
|
+
Util.initDir(assetsDir);
|
|
137
|
+
},
|
|
138
|
+
|
|
119
139
|
saveHtmlReport: async (options) => {
|
|
120
140
|
|
|
121
141
|
const {
|
|
@@ -127,7 +147,6 @@ const Util = {
|
|
|
127
147
|
|
|
128
148
|
outputDir,
|
|
129
149
|
reportDataFile,
|
|
130
|
-
assetsName,
|
|
131
150
|
assetsRelative
|
|
132
151
|
} = options;
|
|
133
152
|
|
|
@@ -226,7 +245,7 @@ const Util = {
|
|
|
226
245
|
writeJSONSync: function(filePath, json) {
|
|
227
246
|
let content = Util.jsonString(json);
|
|
228
247
|
if (!content) {
|
|
229
|
-
|
|
248
|
+
Util.logError('invalid JSON object');
|
|
230
249
|
return false;
|
|
231
250
|
}
|
|
232
251
|
// end of line
|
|
@@ -325,7 +344,7 @@ const Util = {
|
|
|
325
344
|
if (template) {
|
|
326
345
|
Util.templateCache[templatePath] = template;
|
|
327
346
|
} else {
|
|
328
|
-
|
|
347
|
+
Util.logError(`not found template: ${templatePath}`);
|
|
329
348
|
}
|
|
330
349
|
}
|
|
331
350
|
return template;
|
|
@@ -352,6 +371,81 @@ const Util = {
|
|
|
352
371
|
});
|
|
353
372
|
});
|
|
354
373
|
return option;
|
|
374
|
+
},
|
|
375
|
+
|
|
376
|
+
// ==========================================================================================
|
|
377
|
+
|
|
378
|
+
loggingLevels: {
|
|
379
|
+
off: 0,
|
|
380
|
+
error: 10,
|
|
381
|
+
info: 20,
|
|
382
|
+
debug: 30
|
|
383
|
+
},
|
|
384
|
+
|
|
385
|
+
initLoggingLevel: (level, from = '') => {
|
|
386
|
+
if (!level && Util.loggingType) {
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
const types = {
|
|
390
|
+
off: 'off',
|
|
391
|
+
error: 'error',
|
|
392
|
+
info: 'info',
|
|
393
|
+
debug: 'debug'
|
|
394
|
+
};
|
|
395
|
+
const type = types[level] || types.info;
|
|
396
|
+
Util.loggingType = type;
|
|
397
|
+
Util.loggingLevel = Util.loggingLevels[type];
|
|
398
|
+
|
|
399
|
+
// console.log('=========================================');
|
|
400
|
+
// console.log(from, Util.loggingType, Util.loggingLevel);
|
|
401
|
+
},
|
|
402
|
+
|
|
403
|
+
logError: (message) => {
|
|
404
|
+
if (Util.loggingLevel < Util.loggingLevels.error) {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
EC.logRed(`[MCR] ${message}`);
|
|
408
|
+
},
|
|
409
|
+
|
|
410
|
+
logInfo: (message) => {
|
|
411
|
+
if (Util.loggingLevel < Util.loggingLevels.info) {
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
console.log(`[MCR] ${message}`);
|
|
415
|
+
},
|
|
416
|
+
|
|
417
|
+
// grid is info level
|
|
418
|
+
logGrid: (gridData) => {
|
|
419
|
+
if (Util.loggingLevel < Util.loggingLevels.info) {
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
CG(gridData);
|
|
423
|
+
},
|
|
424
|
+
|
|
425
|
+
logDebug: (message) => {
|
|
426
|
+
if (Util.loggingLevel < Util.loggingLevels.debug) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
console.log(`[MCR] ${message}`);
|
|
430
|
+
},
|
|
431
|
+
|
|
432
|
+
// time is debug level
|
|
433
|
+
logTime: (message, time_start) => {
|
|
434
|
+
if (Util.loggingLevel < Util.loggingLevels.debug) {
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
const duration = Date.now() - time_start;
|
|
438
|
+
const durationH = Util.TSF(duration);
|
|
439
|
+
const ls = [`[MCR] ${message}`, ' ('];
|
|
440
|
+
if (duration <= 100) {
|
|
441
|
+
ls.push(EC.green(durationH));
|
|
442
|
+
} else if (duration < 500) {
|
|
443
|
+
ls.push(EC.yellow(durationH));
|
|
444
|
+
} else {
|
|
445
|
+
ls.push(EC.red(durationH));
|
|
446
|
+
}
|
|
447
|
+
ls.push(')');
|
|
448
|
+
console.log(ls.join(''));
|
|
355
449
|
}
|
|
356
450
|
|
|
357
451
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monocart-reporter",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "A playwright test reporter. Shows suites/cases/steps with tree style, markdown annotations, custom columns/formatters/data collection visitors, console logs, style tags, send email.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -48,8 +48,7 @@
|
|
|
48
48
|
"koa-static-resolver": "^1.0.4",
|
|
49
49
|
"lz-utils": "^2.0.1",
|
|
50
50
|
"nodemailer": "^6.9.3",
|
|
51
|
-
"open": "^9.1.0"
|
|
52
|
-
"source-map": "^0.7.4"
|
|
51
|
+
"open": "^9.1.0"
|
|
53
52
|
},
|
|
54
53
|
"devDependencies": {
|
|
55
54
|
"@playwright/test": "^1.35.1",
|
|
@@ -58,8 +57,8 @@
|
|
|
58
57
|
"eslint": "^8.43.0",
|
|
59
58
|
"eslint-config-plus": "^1.0.6",
|
|
60
59
|
"eslint-plugin-html": "^7.1.0",
|
|
61
|
-
"eslint-plugin-vue": "^9.15.
|
|
62
|
-
"stylelint": "^15.
|
|
60
|
+
"eslint-plugin-vue": "^9.15.1",
|
|
61
|
+
"stylelint": "^15.9.0",
|
|
63
62
|
"stylelint-config-plus": "^1.0.3",
|
|
64
63
|
"vine-ui": "^3.1.12"
|
|
65
64
|
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
const findLine = function(list, position) {
|
|
3
|
-
let start = 0;
|
|
4
|
-
let end = list.length - 1;
|
|
5
|
-
while (end - start > 1) {
|
|
6
|
-
const i = Math.floor((start + end) * 0.5);
|
|
7
|
-
const item = list[i];
|
|
8
|
-
if (position < item.start) {
|
|
9
|
-
end = i;
|
|
10
|
-
continue;
|
|
11
|
-
}
|
|
12
|
-
if (position > item.end) {
|
|
13
|
-
start = i;
|
|
14
|
-
continue;
|
|
15
|
-
}
|
|
16
|
-
return list[i];
|
|
17
|
-
}
|
|
18
|
-
// last two items, less is start
|
|
19
|
-
const endItem = list[end];
|
|
20
|
-
if (position < endItem.start) {
|
|
21
|
-
return list[start];
|
|
22
|
-
}
|
|
23
|
-
return list[end];
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
class PositionMapping {
|
|
27
|
-
constructor(source, sourceName) {
|
|
28
|
-
this.source = source;
|
|
29
|
-
this.sourceName = sourceName;
|
|
30
|
-
this.lines = this.getLines(source);
|
|
31
|
-
this.ranges = [];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// =============================================================================
|
|
35
|
-
|
|
36
|
-
getSlice(s, e) {
|
|
37
|
-
return this.source.slice(s, e);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
locationToOffset(location) {
|
|
41
|
-
const { line, column } = location;
|
|
42
|
-
// 1-based
|
|
43
|
-
const lineInfo = this.lines[line - 1];
|
|
44
|
-
if (lineInfo) {
|
|
45
|
-
if (column === Infinity) {
|
|
46
|
-
return lineInfo.start + lineInfo.length;
|
|
47
|
-
}
|
|
48
|
-
return lineInfo.start + column;
|
|
49
|
-
}
|
|
50
|
-
return 0;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
offsetToLocation(offset) {
|
|
54
|
-
const lineInfo = findLine(this.lines, offset);
|
|
55
|
-
const column = Math.min(Math.max(offset - lineInfo.start, 0), lineInfo.length);
|
|
56
|
-
|
|
57
|
-
// 1-based
|
|
58
|
-
const line = lineInfo.line + 1;
|
|
59
|
-
|
|
60
|
-
return {
|
|
61
|
-
line,
|
|
62
|
-
column
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// =============================================================================
|
|
67
|
-
|
|
68
|
-
getLines(content) {
|
|
69
|
-
let pos = 0;
|
|
70
|
-
const lines = content.split(/\n/).map((text, line) => {
|
|
71
|
-
const length = text.length;
|
|
72
|
-
const start = pos;
|
|
73
|
-
const end = start + length;
|
|
74
|
-
|
|
75
|
-
pos += length + 1;
|
|
76
|
-
|
|
77
|
-
return {
|
|
78
|
-
line,
|
|
79
|
-
start,
|
|
80
|
-
end,
|
|
81
|
-
length,
|
|
82
|
-
text
|
|
83
|
-
};
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
return lines;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
module.exports = PositionMapping;
|
|
92
|
-
|
|
@@ -1,451 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const EC = require('eight-colors');
|
|
4
|
-
|
|
5
|
-
const { SourceMapConsumer } = require('source-map');
|
|
6
|
-
|
|
7
|
-
const PositionMapping = require('./position-mapping.js');
|
|
8
|
-
const { dedupeCountRanges } = require('./dedupe.js');
|
|
9
|
-
const { initSourceMapRootAndUrl } = require('../coverage-utils.js');
|
|
10
|
-
|
|
11
|
-
const Concurrency = require('../../../platform/concurrency.js');
|
|
12
|
-
const { convertSourceMap, axios } = require('../../../runtime/monocart-coverage.js');
|
|
13
|
-
const Util = require('../../../utils/util.js');
|
|
14
|
-
|
|
15
|
-
// SourceMapConsumer.GREATEST_LOWER_BOUND = 1;
|
|
16
|
-
// SourceMapConsumer.LEAST_UPPER_BOUND = 2;
|
|
17
|
-
const BIAS = {
|
|
18
|
-
left: SourceMapConsumer.GREATEST_LOWER_BOUND,
|
|
19
|
-
right: SourceMapConsumer.LEAST_UPPER_BOUND
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
// =========================================================================================================
|
|
23
|
-
|
|
24
|
-
const findOriginalPosition = (consumer, line, column, sides) => {
|
|
25
|
-
let original;
|
|
26
|
-
for (const side of sides) {
|
|
27
|
-
original = consumer.originalPositionFor({
|
|
28
|
-
line,
|
|
29
|
-
column,
|
|
30
|
-
bias: BIAS[side]
|
|
31
|
-
});
|
|
32
|
-
if (original.source !== null) {
|
|
33
|
-
break;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
if (original && original.source !== null) {
|
|
37
|
-
return original;
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const findOriginalStartPosition = (consumer, sLoc) => {
|
|
42
|
-
const { line, column } = sLoc;
|
|
43
|
-
return findOriginalPosition(consumer, line, column, ['right', 'left']);
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const findOriginalEndInRange = (consumer, generatedMapping, range) => {
|
|
47
|
-
const { start, end } = range;
|
|
48
|
-
// from -2 (already -1)
|
|
49
|
-
// > start (no need equal)
|
|
50
|
-
for (let i = end - 2; i > start; i--) {
|
|
51
|
-
const loc = generatedMapping.offsetToLocation(i);
|
|
52
|
-
const op = findOriginalPosition(consumer, loc.line, loc.column, ['left', 'right']);
|
|
53
|
-
if (op) {
|
|
54
|
-
return op;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const findOriginalEndPosition = (consumer, eLoc, generatedMapping, range) => {
|
|
60
|
-
const { line, column } = eLoc;
|
|
61
|
-
|
|
62
|
-
// before end column must be >= 0
|
|
63
|
-
const currentColumn = Math.max(column - 1, 0);
|
|
64
|
-
|
|
65
|
-
let ep = findOriginalPosition(consumer, line, currentColumn, ['left', 'right']);
|
|
66
|
-
if (!ep) {
|
|
67
|
-
ep = findOriginalEndInRange(consumer, generatedMapping, range);
|
|
68
|
-
if (!ep) {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const afterEndMapping = consumer.generatedPositionFor({
|
|
74
|
-
source: ep.source,
|
|
75
|
-
line: ep.line,
|
|
76
|
-
column: ep.column + 1,
|
|
77
|
-
bias: BIAS.right
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
if (afterEndMapping.line === null) {
|
|
81
|
-
return {
|
|
82
|
-
source: ep.source,
|
|
83
|
-
line: ep.line,
|
|
84
|
-
column: Infinity
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const mapping = consumer.originalPositionFor(afterEndMapping);
|
|
89
|
-
if (mapping.line !== ep.line) {
|
|
90
|
-
return {
|
|
91
|
-
source: ep.source,
|
|
92
|
-
line: ep.line,
|
|
93
|
-
column: Infinity
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return mapping;
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
// =========================================================================================================
|
|
101
|
-
|
|
102
|
-
const getOriginalMappings = (consumer, options) => {
|
|
103
|
-
|
|
104
|
-
// source filter
|
|
105
|
-
let sourceList = consumer.sources;
|
|
106
|
-
if (typeof options.sourceFilter === 'function') {
|
|
107
|
-
sourceList = sourceList.filter((sourceName) => {
|
|
108
|
-
return options.sourceFilter(sourceName);
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// create original content mappings
|
|
113
|
-
const originalMappings = new Map();
|
|
114
|
-
for (const sourceName of sourceList) {
|
|
115
|
-
// console.log(`add source: ${k}`);
|
|
116
|
-
const sourceContent = consumer.sourceContentFor(sourceName);
|
|
117
|
-
if (typeof sourceContent !== 'string') {
|
|
118
|
-
EC.logRed(`[MCR] not found source content: ${sourceName}`);
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const mapping = new PositionMapping(sourceContent, sourceName);
|
|
123
|
-
originalMappings.set(sourceName, mapping);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return originalMappings;
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
// =========================================================================================================
|
|
130
|
-
|
|
131
|
-
const addOriginalRange = (originalMapping, start, end, count) => {
|
|
132
|
-
originalMapping.ranges.push({
|
|
133
|
-
start,
|
|
134
|
-
end,
|
|
135
|
-
count
|
|
136
|
-
});
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
// =========================================================================================================
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const unpackJsSourceMap = async (item, v8list, options) => {
|
|
143
|
-
// console.log('------------------------------------------------------');
|
|
144
|
-
// console.log(item.type, item.url);
|
|
145
|
-
// console.log(Object.keys(item));
|
|
146
|
-
|
|
147
|
-
const sourceMap = item.sourceMap;
|
|
148
|
-
|
|
149
|
-
const fileUrls = {};
|
|
150
|
-
const fileSources = {};
|
|
151
|
-
initSourceMapRootAndUrl(sourceMap, fileUrls, fileSources);
|
|
152
|
-
|
|
153
|
-
const generatedMapping = new PositionMapping(item.source);
|
|
154
|
-
const consumer = await new SourceMapConsumer(sourceMap);
|
|
155
|
-
const originalMappings = getOriginalMappings(consumer, options);
|
|
156
|
-
|
|
157
|
-
// generated ranges to original ranges
|
|
158
|
-
item.ranges.forEach((range) => {
|
|
159
|
-
|
|
160
|
-
// find start location
|
|
161
|
-
const sLoc = generatedMapping.offsetToLocation(range.start);
|
|
162
|
-
const oSLoc = findOriginalStartPosition(consumer, sLoc);
|
|
163
|
-
if (!oSLoc) {
|
|
164
|
-
// not found start
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// if source excluded
|
|
169
|
-
const currentSource = oSLoc.source;
|
|
170
|
-
const originalMapping = originalMappings.get(currentSource);
|
|
171
|
-
if (!originalMapping) {
|
|
172
|
-
// possible this source has been filtered
|
|
173
|
-
// console.log(`not found source: ${currentSource}`);
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const originalStart = originalMapping.locationToOffset(oSLoc);
|
|
178
|
-
|
|
179
|
-
// find end location
|
|
180
|
-
const eLoc = generatedMapping.offsetToLocation(range.end);
|
|
181
|
-
const oELoc = findOriginalEndPosition(consumer, eLoc, generatedMapping, range);
|
|
182
|
-
if (!oELoc) {
|
|
183
|
-
|
|
184
|
-
// console.log(EC.red('not found end'));
|
|
185
|
-
// console.log(item.url);
|
|
186
|
-
// console.log(originalMapping.sourceName);
|
|
187
|
-
// console.log('generated start', sLoc.line, sLoc.column, 'original start', oSLoc.line, oSLoc.column);
|
|
188
|
-
// console.log('generated end', eLoc.line, eLoc.column);
|
|
189
|
-
|
|
190
|
-
// can NOT use file end
|
|
191
|
-
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
if (oSLoc.source !== oELoc.source) {
|
|
196
|
-
// console.log('ERROR: range crossed source file', range, oSLoc.source, oELoc.source);
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const originalEnd = originalMapping.locationToOffset(oELoc);
|
|
201
|
-
if (originalEnd < originalStart) {
|
|
202
|
-
// range start greater than end
|
|
203
|
-
addOriginalRange(originalMapping, originalEnd, originalStart, range.count);
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
addOriginalRange(originalMapping, originalStart, originalEnd, range.count);
|
|
208
|
-
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
consumer.destroy();
|
|
212
|
-
|
|
213
|
-
// append to v8list
|
|
214
|
-
originalMappings.forEach((originalMapping, currentSource) => {
|
|
215
|
-
|
|
216
|
-
const url = fileUrls[currentSource] || currentSource;
|
|
217
|
-
const ranges = dedupeCountRanges(originalMapping.ranges);
|
|
218
|
-
|
|
219
|
-
// console.log('add source url', url);
|
|
220
|
-
|
|
221
|
-
// original source and id
|
|
222
|
-
const source = originalMapping.source;
|
|
223
|
-
const id = Util.calculateSha1(url + source);
|
|
224
|
-
|
|
225
|
-
let ext = path.extname(currentSource);
|
|
226
|
-
let type = '';
|
|
227
|
-
if (ext) {
|
|
228
|
-
ext = ext.slice(1);
|
|
229
|
-
const reg = /^[a-z0-9]+$/;
|
|
230
|
-
if (reg.test(ext)) {
|
|
231
|
-
type = ext;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
v8list.push({
|
|
237
|
-
url,
|
|
238
|
-
id,
|
|
239
|
-
type,
|
|
240
|
-
sourcePath: currentSource,
|
|
241
|
-
distFile: item.sourceMap.file,
|
|
242
|
-
ranges,
|
|
243
|
-
source
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
});
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
// =========================================================================================================
|
|
250
|
-
|
|
251
|
-
const request = async (options) => {
|
|
252
|
-
if (typeof options === 'string') {
|
|
253
|
-
options = {
|
|
254
|
-
url: options
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
let err;
|
|
258
|
-
const res = await axios(options).catch((e) => {
|
|
259
|
-
err = e;
|
|
260
|
-
});
|
|
261
|
-
return [err, res];
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
const getSourceMapUrl = (content, url) => {
|
|
265
|
-
|
|
266
|
-
const m = content.match(convertSourceMap.mapFileCommentRegex);
|
|
267
|
-
if (!m) {
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const comment = m.pop();
|
|
272
|
-
const r = convertSourceMap.mapFileCommentRegex.exec(comment);
|
|
273
|
-
// for some odd reason //# .. captures in 1 and /* .. */ in 2
|
|
274
|
-
const filename = r[1] || r[2];
|
|
275
|
-
|
|
276
|
-
let mapUrl;
|
|
277
|
-
|
|
278
|
-
try {
|
|
279
|
-
mapUrl = new URL(filename, url);
|
|
280
|
-
} catch (e) {
|
|
281
|
-
// console.log(e)
|
|
282
|
-
}
|
|
283
|
-
if (mapUrl) {
|
|
284
|
-
return mapUrl.toString();
|
|
285
|
-
}
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
const resolveSourceMap = (data) => {
|
|
289
|
-
if (data) {
|
|
290
|
-
const { sources, sourcesContent } = data;
|
|
291
|
-
if (!sources || !sourcesContent) {
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
return data;
|
|
295
|
-
}
|
|
296
|
-
};
|
|
297
|
-
|
|
298
|
-
const collectInlineSourceMaps = async (v8list) => {
|
|
299
|
-
const concurrency = new Concurrency();
|
|
300
|
-
for (const item of v8list) {
|
|
301
|
-
|
|
302
|
-
const { type, source } = item;
|
|
303
|
-
|
|
304
|
-
// only for js
|
|
305
|
-
if (type === 'js') {
|
|
306
|
-
const converter = convertSourceMap.fromSource(source);
|
|
307
|
-
if (converter) {
|
|
308
|
-
item.sourceMap = resolveSourceMap(converter.sourcemap);
|
|
309
|
-
continue;
|
|
310
|
-
}
|
|
311
|
-
const sourceMapUrl = getSourceMapUrl(source, item.url);
|
|
312
|
-
if (sourceMapUrl) {
|
|
313
|
-
item.sourceMapUrl = sourceMapUrl;
|
|
314
|
-
concurrency.addItem(item);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
await concurrency.start(async (item) => {
|
|
319
|
-
const [err, res] = await request({
|
|
320
|
-
url: item.sourceMapUrl
|
|
321
|
-
});
|
|
322
|
-
if (!err && res) {
|
|
323
|
-
item.sourceMap = resolveSourceMap(res.data);
|
|
324
|
-
}
|
|
325
|
-
});
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
const collectFileSourceMaps = async (v8list, options) => {
|
|
329
|
-
const concurrency = new Concurrency();
|
|
330
|
-
for (const item of v8list) {
|
|
331
|
-
|
|
332
|
-
const {
|
|
333
|
-
type, url, source, id
|
|
334
|
-
} = item;
|
|
335
|
-
|
|
336
|
-
// remove source just keep functions to reduce artifacts size
|
|
337
|
-
delete item.source;
|
|
338
|
-
|
|
339
|
-
const sourcePath = Util.resolveArtifactSourcePath(options.artifactsDir, id);
|
|
340
|
-
if (fs.existsSync(sourcePath)) {
|
|
341
|
-
continue;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
const sourceData = {
|
|
345
|
-
url,
|
|
346
|
-
id,
|
|
347
|
-
source: convertSourceMap.removeComments(source)
|
|
348
|
-
};
|
|
349
|
-
|
|
350
|
-
// only for js
|
|
351
|
-
if (type === 'js') {
|
|
352
|
-
const converter = convertSourceMap.fromSource(source);
|
|
353
|
-
if (converter) {
|
|
354
|
-
sourceData.sourceMap = resolveSourceMap(converter.sourcemap);
|
|
355
|
-
await saveSourceFile(sourcePath, sourceData);
|
|
356
|
-
continue;
|
|
357
|
-
}
|
|
358
|
-
const sourceMapUrl = getSourceMapUrl(source, item.url);
|
|
359
|
-
if (sourceMapUrl) {
|
|
360
|
-
concurrency.addItem({
|
|
361
|
-
sourceMapUrl,
|
|
362
|
-
sourcePath,
|
|
363
|
-
sourceData
|
|
364
|
-
});
|
|
365
|
-
continue;
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
await saveSourceFile(sourcePath, sourceData);
|
|
370
|
-
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
await concurrency.start(async (item) => {
|
|
374
|
-
const [err, res] = await request({
|
|
375
|
-
url: item.sourceMapUrl
|
|
376
|
-
});
|
|
377
|
-
const sourceData = item.sourceData;
|
|
378
|
-
if (!err && res) {
|
|
379
|
-
sourceData.sourceMap = resolveSourceMap(res.data);
|
|
380
|
-
}
|
|
381
|
-
await saveSourceFile(item.sourcePath, sourceData);
|
|
382
|
-
});
|
|
383
|
-
};
|
|
384
|
-
|
|
385
|
-
const saveSourceFile = async (filePath, data) => {
|
|
386
|
-
await Util.writeFile(filePath, JSON.stringify(data));
|
|
387
|
-
};
|
|
388
|
-
|
|
389
|
-
const collectSourceMaps = async (v8list, options, inlineSourceMap) => {
|
|
390
|
-
|
|
391
|
-
if (inlineSourceMap) {
|
|
392
|
-
await collectInlineSourceMaps(v8list);
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
await collectFileSourceMaps(v8list, options);
|
|
397
|
-
|
|
398
|
-
};
|
|
399
|
-
|
|
400
|
-
// =========================================================================================================
|
|
401
|
-
const filterSourceMapList = (v8list, options) => {
|
|
402
|
-
const sourceMapList = [];
|
|
403
|
-
const indexes = [];
|
|
404
|
-
|
|
405
|
-
v8list.forEach((item, i) => {
|
|
406
|
-
const sourceMap = item.sourceMap;
|
|
407
|
-
if (!sourceMap) {
|
|
408
|
-
return;
|
|
409
|
-
}
|
|
410
|
-
sourceMapList.push(item);
|
|
411
|
-
indexes.push(i);
|
|
412
|
-
});
|
|
413
|
-
|
|
414
|
-
if (!sourceMapList.length) {
|
|
415
|
-
return;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
// do not remove in debug mode
|
|
419
|
-
if (!options.debug) {
|
|
420
|
-
// remove dist file if found sourceMap
|
|
421
|
-
indexes.reverse();
|
|
422
|
-
indexes.forEach((i) => {
|
|
423
|
-
v8list.splice(i, 1);
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
return sourceMapList;
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
// requires ranges before unpack
|
|
431
|
-
const unpackSourceMaps = async (v8list, options) => {
|
|
432
|
-
|
|
433
|
-
const sourceMapList = filterSourceMapList(v8list, options);
|
|
434
|
-
if (!sourceMapList) {
|
|
435
|
-
// nothing to unpack
|
|
436
|
-
return;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
// console.log(sourceMapList);
|
|
440
|
-
|
|
441
|
-
// only js
|
|
442
|
-
for (const item of sourceMapList) {
|
|
443
|
-
await unpackJsSourceMap(item, v8list, options);
|
|
444
|
-
}
|
|
445
|
-
};
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
module.exports = {
|
|
449
|
-
collectSourceMaps,
|
|
450
|
-
unpackSourceMaps
|
|
451
|
-
};
|