monocart-reporter 1.7.0 → 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 +8 -12
- package/lib/cli.js +1 -1
- package/lib/common.js +2 -3
- package/lib/default/options.js +4 -3
- package/lib/generate-data.js +2 -7
- package/lib/generate-report.js +10 -11
- package/lib/index.d.ts +2 -9
- 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 +61 -57
- package/lib/plugins/coverage/istanbul/istanbul.js +21 -174
- package/lib/plugins/coverage/v8/v8.js +22 -30
- 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 +5 -6
- package/lib/plugins/coverage/v8/position-mapping.js +0 -92
- package/lib/plugins/coverage/v8/source-map.js +0 -464
package/README.md
CHANGED
|
@@ -119,13 +119,14 @@ Separated metadata file (Already included in the above HTML and compressed, it c
|
|
|
119
119
|
|
|
120
120
|
traceViewerUrl: 'https://trace.playwright.dev/?trace={traceUrl}',
|
|
121
121
|
|
|
122
|
+
// logging levels: off, error, info, debug
|
|
123
|
+
logging: 'info',
|
|
124
|
+
|
|
122
125
|
// global coverage settings for addCoverageReport API
|
|
123
126
|
coverage: null,
|
|
124
127
|
// coverage: {
|
|
125
128
|
// entryFilter: (entry) => true,
|
|
126
|
-
//
|
|
127
|
-
// excludeDistFile: true,
|
|
128
|
-
// sourceFilter: (sourceName) => sourceName.search(/src\/.+/) !== -1,
|
|
129
|
+
// sourceFilter: (sourcePath) => sourcePath.search(/src\/.+/) !== -1,
|
|
129
130
|
// },
|
|
130
131
|
|
|
131
132
|
// trend data handler
|
|
@@ -630,16 +631,13 @@ Attach a code coverage report with API `attachCoverageReport(data, testInfo, opt
|
|
|
630
631
|
- `testInfo` see [TestInfo](https://playwright.dev/docs/api/class-testinfo)
|
|
631
632
|
- `options` (Object)
|
|
632
633
|
- `title` (String) report title.
|
|
633
|
-
- `toIstanbul` (Boolean) Whether to convert to Istanbul report from V8 list.
|
|
634
|
+
- `toIstanbul` (Boolean) Whether to convert to Istanbul report from V8 list. Defaults to `html-spa` report | (String) or using `html` report
|
|
634
635
|
- `entryFilter` (Function) A filter function to execute for each element in the V8 list.
|
|
635
|
-
- `unpackSourceMap` (Boolean) Whether to unpack all sources from the source map if a related source map file is found.
|
|
636
|
-
- `excludeDistFile` (Boolean) Whether to exclude the dist file (usually minified) if the sources are successfully unpacked from the source map.
|
|
637
636
|
- `sourceFilter` (Function) A filter function to execute for each element in the sources which unpacked from the source map.
|
|
638
637
|
- `watermarks` (Object) Istanbul watermarks, see [here](https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-lib-report) | (Array) V8 watermarks, Defaults to `[50, 80]`.
|
|
639
638
|
- `lcov` (Boolean) Whether to create `lcov.info`. Istanbul only.
|
|
640
639
|
- `sourcePath` (Function) source path handler, return a new source path. Istanbul only.
|
|
641
|
-
- `inline` (Boolean) Whether inline all scripts to the single HTML file.
|
|
642
|
-
- `debug` (Boolean) The temporary artifacts will not be removed.
|
|
640
|
+
- `inline` (Boolean) Whether inline all scripts to the single HTML file. V8 only.
|
|
643
641
|
|
|
644
642
|
(see example: [report-coverage.spec.js](https://github.com/cenfun/monocart-reporter/blob/main/tests/report-coverage/report-coverage.spec.js))
|
|
645
643
|
|
|
@@ -705,7 +703,7 @@ test('Take V8 and Istanbul coverage report', async ({ page }) => {
|
|
|
705
703
|
const coverageList = [... jsCoverage, ... cssCoverage];
|
|
706
704
|
|
|
707
705
|
const v8 = await attachCoverageReport(coverageList, test.info(), {
|
|
708
|
-
|
|
706
|
+
|
|
709
707
|
});
|
|
710
708
|
console.log(v8.summary);
|
|
711
709
|
|
|
@@ -745,9 +743,7 @@ module.exports = {
|
|
|
745
743
|
// global coverage report options
|
|
746
744
|
coverage: {
|
|
747
745
|
entryFilter: (entry) => true,
|
|
748
|
-
|
|
749
|
-
excludeDistFile: true,
|
|
750
|
-
sourceFilter: (sourceName) => sourceName.search(/src\/.+/) !== -1,
|
|
746
|
+
sourceFilter: (sourcePath) => sourcePath.search(/src\/.+/) !== -1,
|
|
751
747
|
}
|
|
752
748
|
}]
|
|
753
749
|
]
|
package/lib/cli.js
CHANGED
package/lib/common.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const EC = require('eight-colors');
|
|
2
1
|
const Util = require('./utils/util.js');
|
|
3
2
|
const defaultSummary = require('./default/summary.js');
|
|
4
3
|
const generatePieChart = require('./utils/pie.js');
|
|
@@ -205,12 +204,12 @@ const getTrends = async (input) => {
|
|
|
205
204
|
}
|
|
206
205
|
const data = await getTrendData(input);
|
|
207
206
|
if (!data) {
|
|
208
|
-
|
|
207
|
+
Util.logError('failed to load trend data');
|
|
209
208
|
return [];
|
|
210
209
|
}
|
|
211
210
|
|
|
212
211
|
if (!isTrendData(data)) {
|
|
213
|
-
|
|
212
|
+
Util.logError('trend data requires properties: date, duration and summary');
|
|
214
213
|
return [];
|
|
215
214
|
}
|
|
216
215
|
|
package/lib/default/options.js
CHANGED
|
@@ -11,13 +11,14 @@ module.exports = {
|
|
|
11
11
|
|
|
12
12
|
traceViewerUrl: 'https://trace.playwright.dev/?trace={traceUrl}',
|
|
13
13
|
|
|
14
|
+
// logging levels: off, error, info, debug
|
|
15
|
+
logging: 'info',
|
|
16
|
+
|
|
14
17
|
// global coverage settings for addCoverageReport API
|
|
15
18
|
coverage: null,
|
|
16
19
|
// coverage: {
|
|
17
20
|
// entryFilter: (entry) => true,
|
|
18
|
-
//
|
|
19
|
-
// excludeDistFile: true,
|
|
20
|
-
// sourceFilter: (sourceName) => sourceName.search(/src\/.+/) !== -1,
|
|
21
|
+
// sourceFilter: (sourcePath) => sourcePath.search(/src\/.+/) !== -1,
|
|
21
22
|
// },
|
|
22
23
|
|
|
23
24
|
state: null,
|
package/lib/generate-data.js
CHANGED
|
@@ -5,7 +5,6 @@ const { getTickInfo } = require('./utils/system.js');
|
|
|
5
5
|
const Visitor = require('./visitor.js');
|
|
6
6
|
const { calculateSummary } = require('./common.js');
|
|
7
7
|
const { generateGlobalCoverageReport } = require('./plugins/coverage/coverage.js');
|
|
8
|
-
const { generateGlobalNetworkReport } = require('./plugins/network/network.js');
|
|
9
8
|
const version = require('../package.json').version;
|
|
10
9
|
|
|
11
10
|
const getReportName = (options, config, metadata) => {
|
|
@@ -19,21 +18,17 @@ const getReportName = (options, config, metadata) => {
|
|
|
19
18
|
const artifactsHandler = async (visitor, options) => {
|
|
20
19
|
const artifacts = [].concat(visitor.artifacts);
|
|
21
20
|
// global artifacts
|
|
22
|
-
const { coverage
|
|
21
|
+
const { coverage } = visitor.artifactDataMap;
|
|
23
22
|
if (coverage) {
|
|
24
23
|
const report = await generateGlobalCoverageReport(coverage, options);
|
|
25
24
|
artifacts.push(report);
|
|
26
25
|
}
|
|
27
|
-
if (network) {
|
|
28
|
-
const report = await generateGlobalNetworkReport(coverage, options);
|
|
29
|
-
artifacts.push(report);
|
|
30
|
-
}
|
|
31
26
|
return artifacts;
|
|
32
27
|
};
|
|
33
28
|
|
|
34
29
|
const generateData = async (results) => {
|
|
35
30
|
|
|
36
|
-
|
|
31
|
+
Util.logInfo('generating report data ...');
|
|
37
32
|
|
|
38
33
|
const {
|
|
39
34
|
config,
|
package/lib/generate-report.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const EC = require('eight-colors');
|
|
3
|
-
const CG = require('console-grid');
|
|
4
3
|
const nodemailer = require('nodemailer');
|
|
5
4
|
const Util = require('./utils/util.js');
|
|
6
5
|
const emailPlugin = require('./plugins/email.js');
|
|
@@ -12,7 +11,7 @@ const generateJson = (outputDir, htmlFile, reportData) => {
|
|
|
12
11
|
let jsonPath = path.resolve(outputDir, `${filename}.json`);
|
|
13
12
|
Util.writeJSONSync(jsonPath, reportData);
|
|
14
13
|
jsonPath = Util.relativePath(jsonPath);
|
|
15
|
-
|
|
14
|
+
Util.logInfo(`json report: ${EC.cyan(jsonPath)}`);
|
|
16
15
|
return jsonPath;
|
|
17
16
|
};
|
|
18
17
|
|
|
@@ -27,31 +26,30 @@ const generateHtml = async (outputDir, htmlFile, reportData, inline) => {
|
|
|
27
26
|
|
|
28
27
|
outputDir,
|
|
29
28
|
reportDataFile: 'report-data.js',
|
|
30
|
-
assetsName: 'assets',
|
|
31
29
|
assetsRelative: ''
|
|
32
30
|
};
|
|
33
31
|
|
|
34
32
|
const htmlPath = await Util.saveHtmlReport(options);
|
|
35
|
-
|
|
33
|
+
Util.logInfo(`html report: ${EC.cyan(htmlPath)}`);
|
|
36
34
|
|
|
37
35
|
const cmd = `npx monocart show-report ${htmlPath}`;
|
|
38
|
-
|
|
36
|
+
Util.logInfo(`view report: ${EC.cyan(cmd)}`);
|
|
39
37
|
|
|
40
38
|
return htmlPath;
|
|
41
39
|
};
|
|
42
40
|
|
|
43
41
|
const sendEmail = (emailOptions) => {
|
|
44
42
|
if (!emailOptions.transport || !emailOptions.message) {
|
|
45
|
-
|
|
43
|
+
Util.logError('invalid email options, transport and message are required (https://nodemailer.com/)');
|
|
46
44
|
return;
|
|
47
45
|
}
|
|
48
|
-
|
|
46
|
+
Util.logInfo('sending email ...');
|
|
49
47
|
const transporter = nodemailer.createTransport(emailOptions.transport);
|
|
50
48
|
return transporter.sendMail(emailOptions.message);
|
|
51
49
|
};
|
|
52
50
|
|
|
53
51
|
const showTestResults = (reportData) => {
|
|
54
|
-
|
|
52
|
+
Util.logInfo(`test results: ${EC.cyan(reportData.name)}`);
|
|
55
53
|
|
|
56
54
|
const summary = reportData.summary;
|
|
57
55
|
|
|
@@ -127,7 +125,7 @@ const showTestResults = (reportData) => {
|
|
|
127
125
|
value: Util.TF(reportData.duration)
|
|
128
126
|
}]);
|
|
129
127
|
|
|
130
|
-
|
|
128
|
+
Util.logGrid({
|
|
131
129
|
options: {
|
|
132
130
|
headerVisible: false
|
|
133
131
|
},
|
|
@@ -138,12 +136,13 @@ const showTestResults = (reportData) => {
|
|
|
138
136
|
}],
|
|
139
137
|
rows
|
|
140
138
|
});
|
|
139
|
+
|
|
141
140
|
};
|
|
142
141
|
|
|
143
142
|
|
|
144
143
|
const generateReport = async (reportData, options) => {
|
|
145
144
|
|
|
146
|
-
|
|
145
|
+
Util.logInfo('generating test report ...');
|
|
147
146
|
showTestResults(reportData);
|
|
148
147
|
|
|
149
148
|
const {
|
|
@@ -153,7 +152,7 @@ const generateReport = async (reportData, options) => {
|
|
|
153
152
|
if (artifacts) {
|
|
154
153
|
artifacts.forEach((report) => {
|
|
155
154
|
const g = report.global ? `${EC.magenta('(global)')}` : '';
|
|
156
|
-
|
|
155
|
+
Util.logInfo(`${report.name}: ${EC.cyan(report.path)} ${report.title} ${g}`);
|
|
157
156
|
// convert path to relative reporter
|
|
158
157
|
report.path = Util.relativePath(report.path, outputDir);
|
|
159
158
|
});
|
package/lib/index.d.ts
CHANGED
|
@@ -39,16 +39,11 @@ export type CoverageReportOptions = {
|
|
|
39
39
|
outputName?: string,
|
|
40
40
|
|
|
41
41
|
// Whether to convert to Istanbul report
|
|
42
|
-
toIstanbul?: boolean,
|
|
42
|
+
toIstanbul?: boolean | string,
|
|
43
43
|
|
|
44
44
|
// A filter function to execute for each element in the V8 list.
|
|
45
45
|
entryFilter?: (entry: any) => boolean,
|
|
46
46
|
|
|
47
|
-
// Whether to unpack all sources from the source map if a related source map file is found.
|
|
48
|
-
unpackSourceMap?: boolean,
|
|
49
|
-
// Whether to exclude the dist file (usually minified) if the sources are successfully unpacked from the source map.
|
|
50
|
-
excludeDistFile?: boolean,
|
|
51
|
-
|
|
52
47
|
// A filter function to execute for each element in the sources which unpacked from the source map.
|
|
53
48
|
sourceFilter?: (sourcePath: string) => boolean,
|
|
54
49
|
|
|
@@ -67,9 +62,7 @@ export type CoverageReportOptions = {
|
|
|
67
62
|
},
|
|
68
63
|
|
|
69
64
|
// Whether inline all scripts to the single HTML file.
|
|
70
|
-
inline?: boolean
|
|
71
|
-
|
|
72
|
-
debug?: boolean
|
|
65
|
+
inline?: boolean
|
|
73
66
|
};
|
|
74
67
|
|
|
75
68
|
export function attachCoverageReport(
|
package/lib/index.js
CHANGED
|
@@ -11,6 +11,7 @@ const { addCoverageReport, attachCoverageReport } = require('./plugins/coverage/
|
|
|
11
11
|
const { attachNetworkReport } = require('./plugins/network/network.js');
|
|
12
12
|
|
|
13
13
|
const { createStateServer, useState } = require('./plugins/state/state.js');
|
|
14
|
+
const Util = require('./utils/util.js');
|
|
14
15
|
|
|
15
16
|
// custom reporter
|
|
16
17
|
// https://playwright.dev/docs/test-reporters#custom-reporters
|
|
@@ -36,6 +37,8 @@ class Reporter {
|
|
|
36
37
|
... userOptions
|
|
37
38
|
};
|
|
38
39
|
|
|
40
|
+
Util.initLoggingLevel(this.options.logging, 'reporter');
|
|
41
|
+
|
|
39
42
|
this.system = getSystemInfo();
|
|
40
43
|
this.system.timestampStart = timestampStart;
|
|
41
44
|
this.system.ticks = [];
|
|
@@ -47,6 +50,9 @@ class Reporter {
|
|
|
47
50
|
this.tickTime = this.options.tickTime || 1000;
|
|
48
51
|
this.tickStart();
|
|
49
52
|
|
|
53
|
+
// clean assets dir
|
|
54
|
+
Util.initAssetsDir(this.options);
|
|
55
|
+
|
|
50
56
|
const stateOptions = this.options.state;
|
|
51
57
|
if (stateOptions) {
|
|
52
58
|
this.stateServer = createStateServer(stateOptions);
|
package/lib/merge-data.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const EC = require('eight-colors');
|
|
4
3
|
const Util = require('./utils/util.js');
|
|
5
4
|
const generateReport = require('./generate-report.js');
|
|
6
5
|
const defaultOptions = require('./default/options.js');
|
|
@@ -16,7 +15,7 @@ const checkReportData = (item) => {
|
|
|
16
15
|
|
|
17
16
|
const initDataList = (reportDataList) => {
|
|
18
17
|
if (!Util.isList(reportDataList)) {
|
|
19
|
-
|
|
18
|
+
Util.logError(`invalid report data list: ${reportDataList}`);
|
|
20
19
|
return;
|
|
21
20
|
}
|
|
22
21
|
|
|
@@ -28,16 +27,16 @@ const initDataList = (reportDataList) => {
|
|
|
28
27
|
const data = Util.readJSONSync(item);
|
|
29
28
|
if (!data) {
|
|
30
29
|
hasError = true;
|
|
31
|
-
|
|
30
|
+
Util.logError(`failed to read report data file: ${item}`);
|
|
32
31
|
continue;
|
|
33
32
|
}
|
|
34
33
|
list.push(data);
|
|
35
|
-
|
|
34
|
+
Util.logInfo(`report data loaded: ${item}`);
|
|
36
35
|
continue;
|
|
37
36
|
}
|
|
38
37
|
|
|
39
38
|
if (!checkReportData(item)) {
|
|
40
|
-
|
|
39
|
+
Util.logError(`unmatched report data format: ${item}`);
|
|
41
40
|
return;
|
|
42
41
|
}
|
|
43
42
|
list.push(item);
|
|
@@ -164,7 +163,9 @@ const mergeDataList = async (dataList, options) => {
|
|
|
164
163
|
|
|
165
164
|
module.exports = async (reportDataList, userOptions = {}) => {
|
|
166
165
|
|
|
167
|
-
|
|
166
|
+
Util.initLoggingLevel(userOptions.logging, 'merge');
|
|
167
|
+
|
|
168
|
+
Util.logInfo('merging report data ...');
|
|
168
169
|
|
|
169
170
|
const dataList = await initDataList(reportDataList);
|
|
170
171
|
if (!dataList) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const EC = require('eight-colors');
|
|
4
3
|
const Util = require('../../utils/util.js');
|
|
5
4
|
|
|
6
5
|
const getStatus = (s) => {
|
|
@@ -65,8 +64,11 @@ const getSummaryReport = (lhr) => {
|
|
|
65
64
|
|
|
66
65
|
const attachAuditReport = async (runnerResult, testInfo, options = {}) => {
|
|
67
66
|
|
|
67
|
+
const reporterOptions = Util.resolveReporterOptions(testInfo);
|
|
68
|
+
Util.initLoggingLevel(reporterOptions.logging, 'audit');
|
|
69
|
+
|
|
68
70
|
if (!runnerResult || !runnerResult.lhr || !runnerResult.report) {
|
|
69
|
-
|
|
71
|
+
Util.logError('invalid lighthouse runner result');
|
|
70
72
|
return;
|
|
71
73
|
}
|
|
72
74
|
|
package/lib/plugins/comments.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
|
-
const EC = require('eight-colors');
|
|
3
2
|
const { parse } = require('../runtime/monocart-vendor.js');
|
|
4
3
|
const Util = require('../utils/util.js');
|
|
5
4
|
|
|
@@ -32,8 +31,8 @@ const getFileComments = (filePath, parserOptions = {}) => {
|
|
|
32
31
|
try {
|
|
33
32
|
ast = parse(source, parserOptions);
|
|
34
33
|
} catch (e) {
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
Util.logError(e.message);
|
|
35
|
+
Util.logError(`failed to collect comments from the file: ${Util.relativePath(filePath)}`);
|
|
37
36
|
return map;
|
|
38
37
|
}
|
|
39
38
|
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const EC = require('eight-colors');
|
|
3
|
+
const { fileURLToPath } = require('url');
|
|
4
|
+
const Concurrency = require('../../../platform/concurrency.js');
|
|
5
|
+
const { convertSourceMap, axios } = require('../../../runtime/monocart-coverage.js');
|
|
6
|
+
|
|
7
|
+
const Util = require('../../../utils/util.js');
|
|
8
|
+
|
|
9
|
+
const request = async (options) => {
|
|
10
|
+
if (typeof options === 'string') {
|
|
11
|
+
options = {
|
|
12
|
+
url: options
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
let err;
|
|
16
|
+
const res = await axios(options).catch((e) => {
|
|
17
|
+
err = e;
|
|
18
|
+
});
|
|
19
|
+
return [err, res];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const loadSourceMap = async (url = '') => {
|
|
23
|
+
|
|
24
|
+
if (url.startsWith('file://')) {
|
|
25
|
+
const p = fileURLToPath(url);
|
|
26
|
+
const json = Util.readJSONSync(p);
|
|
27
|
+
if (!json) {
|
|
28
|
+
Util.logDebug(EC.red(`failed to load sourcemap ${p}`));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
return json;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const [err, res] = await request({
|
|
35
|
+
url
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
if (err) {
|
|
39
|
+
Util.logDebug(EC.red(`${err.message} ${url}`));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return res.data;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const getSourceMapUrl = (content, url) => {
|
|
47
|
+
|
|
48
|
+
const m = content.match(convertSourceMap.mapFileCommentRegex);
|
|
49
|
+
if (!m) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const comment = m.pop();
|
|
54
|
+
const r = convertSourceMap.mapFileCommentRegex.exec(comment);
|
|
55
|
+
// for some odd reason //# .. captures in 1 and /* .. */ in 2
|
|
56
|
+
const filename = r[1] || r[2];
|
|
57
|
+
|
|
58
|
+
let mapUrl;
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
mapUrl = new URL(filename, url);
|
|
62
|
+
} catch (e) {
|
|
63
|
+
Util.logDebug(EC.red(`${e.message} ${filename} ${url}`));
|
|
64
|
+
}
|
|
65
|
+
if (mapUrl) {
|
|
66
|
+
return mapUrl.toString();
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const resolveSourceMap = (data) => {
|
|
71
|
+
if (data) {
|
|
72
|
+
const {
|
|
73
|
+
sources, sourcesContent, mappings
|
|
74
|
+
} = data;
|
|
75
|
+
if (!sources || !sourcesContent || !mappings) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
return data;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const collectInlineSourceMaps = async (v8list) => {
|
|
83
|
+
let count = 0;
|
|
84
|
+
const concurrency = new Concurrency();
|
|
85
|
+
for (const item of v8list) {
|
|
86
|
+
|
|
87
|
+
const { type, source } = item;
|
|
88
|
+
|
|
89
|
+
// only for js
|
|
90
|
+
if (type === 'js') {
|
|
91
|
+
const converter = convertSourceMap.fromSource(source);
|
|
92
|
+
if (converter) {
|
|
93
|
+
item.sourceMap = resolveSourceMap(converter.sourcemap);
|
|
94
|
+
count += 1;
|
|
95
|
+
// source map comments is inline source map, remove it because it is big
|
|
96
|
+
item.source = convertSourceMap.removeComments(source);
|
|
97
|
+
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const sourceMapUrl = getSourceMapUrl(source, item.url);
|
|
101
|
+
if (sourceMapUrl) {
|
|
102
|
+
// console.log('========================', sourceMapUrl);
|
|
103
|
+
item.sourceMapUrl = sourceMapUrl;
|
|
104
|
+
concurrency.addItem(item);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
await concurrency.start(async (item) => {
|
|
109
|
+
const data = await loadSourceMap(item.sourceMapUrl);
|
|
110
|
+
if (data) {
|
|
111
|
+
item.sourceMap = resolveSourceMap(data);
|
|
112
|
+
count += 1;
|
|
113
|
+
// source map comments is a link, no need remove
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
return count;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const collectFileSourceMaps = async (v8list, options) => {
|
|
121
|
+
let count = 0;
|
|
122
|
+
const concurrency = new Concurrency();
|
|
123
|
+
for (const item of v8list) {
|
|
124
|
+
|
|
125
|
+
const {
|
|
126
|
+
type, url, source, id
|
|
127
|
+
} = item;
|
|
128
|
+
|
|
129
|
+
// remove source just keep functions to reduce artifacts size
|
|
130
|
+
delete item.source;
|
|
131
|
+
|
|
132
|
+
const sourcePath = Util.resolveArtifactSourcePath(options.artifactsDir, id);
|
|
133
|
+
if (fs.existsSync(sourcePath)) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const sourceData = {
|
|
138
|
+
url,
|
|
139
|
+
id,
|
|
140
|
+
source: convertSourceMap.removeComments(source)
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
// only for js
|
|
144
|
+
if (type === 'js') {
|
|
145
|
+
const converter = convertSourceMap.fromSource(source);
|
|
146
|
+
if (converter) {
|
|
147
|
+
sourceData.sourceMap = resolveSourceMap(converter.sourcemap);
|
|
148
|
+
count += 1;
|
|
149
|
+
await saveSourceFile(sourcePath, sourceData);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const sourceMapUrl = getSourceMapUrl(source, item.url);
|
|
153
|
+
if (sourceMapUrl) {
|
|
154
|
+
concurrency.addItem({
|
|
155
|
+
sourceMapUrl,
|
|
156
|
+
sourcePath,
|
|
157
|
+
sourceData
|
|
158
|
+
});
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
await saveSourceFile(sourcePath, sourceData);
|
|
164
|
+
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
await concurrency.start(async (item) => {
|
|
168
|
+
const sourceData = item.sourceData;
|
|
169
|
+
const data = await loadSourceMap(item.sourceMapUrl);
|
|
170
|
+
if (data) {
|
|
171
|
+
sourceData.sourceMap = resolveSourceMap(data);
|
|
172
|
+
count += 1;
|
|
173
|
+
}
|
|
174
|
+
await saveSourceFile(item.sourcePath, sourceData);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
return count;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const saveSourceFile = async (filePath, data) => {
|
|
181
|
+
await Util.writeFile(filePath, JSON.stringify(data));
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const collectSourceMaps = (v8list, options, inlineSourceMap) => {
|
|
185
|
+
|
|
186
|
+
if (inlineSourceMap) {
|
|
187
|
+
return collectInlineSourceMaps(v8list);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return collectFileSourceMaps(v8list, options);
|
|
191
|
+
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
module.exports = collectSourceMaps;
|