monocart-coverage-reports 2.13.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +267 -114
- package/README.zh-Hans.md +268 -115
- package/lib/assets.js +6 -6
- package/lib/cli.js +191 -95
- package/lib/client/cdp-client.js +74 -43
- package/lib/client/coverage-client.js +24 -8
- package/lib/client/ws-session.js +115 -37
- package/lib/converter/ast-visitor.js +5 -7
- package/lib/converter/ast.js +6 -6
- package/lib/converter/collect-source-maps.js +119 -92
- package/lib/converter/converter.js +49 -117
- package/lib/converter/fake-source-coverage.js +64 -0
- package/lib/converter/find-original-range.js +3 -3
- package/lib/converter/flatten-source-maps.js +2 -4
- package/lib/converter/ignore.js +2 -4
- package/lib/converter/info-branch.js +5 -3
- package/lib/converter/info-function.js +5 -3
- package/lib/converter/info-statement.js +5 -3
- package/lib/converter/range-index.js +78 -0
- package/lib/converter/source-range-merge.js +103 -0
- package/lib/converter/untested.js +27 -55
- package/lib/default/options.js +13 -1
- package/lib/generate.js +44 -26
- package/lib/index.d.ts +52 -4
- package/lib/index.js +35 -41
- package/lib/istanbul/istanbul-summary.js +2 -2
- package/lib/istanbul/istanbul.js +35 -13
- package/lib/packages/chunks/chunk-RVOSNMVU.js +2 -0
- package/lib/packages/monocart-coverage-assets.js +4 -3
- package/lib/packages/monocart-coverage-converter.js +27 -0
- package/lib/packages/monocart-coverage-vendor.js +2 -41
- package/lib/packages/monocart-coverage-vendor.js.LICENSE +3 -221
- package/lib/platform/concurrency.js +47 -43
- package/lib/platform/share.js +1 -1
- package/lib/register/hooks.js +19 -13
- package/lib/register/register.js +5 -3
- package/lib/reports/codacy.js +3 -5
- package/lib/reports/codecov.js +3 -5
- package/lib/reports/console-details.js +5 -5
- package/lib/reports/console-summary.js +4 -4
- package/lib/reports/custom.js +8 -24
- package/lib/reports/markdown-details.js +4 -6
- package/lib/reports/markdown-summary.js +4 -6
- package/lib/reports/raw.js +10 -12
- package/lib/reports/v8-json.js +3 -5
- package/lib/reports/v8.js +3 -5
- package/lib/utils/dedupe.js +1 -1
- package/lib/utils/gc.js +30 -14
- package/lib/utils/markdown.js +2 -2
- package/lib/utils/merge/merge.js +2 -4
- package/lib/utils/merge/range-tree.js +1 -1
- package/lib/utils/request.js +85 -73
- package/lib/utils/snapshot.js +4 -4
- package/lib/utils/source-path.js +5 -5
- package/lib/utils/util.js +61 -41
- package/lib/v8/v8-summary.js +2 -4
- package/lib/v8/v8.js +11 -11
- package/migrate-to-3.md +175 -0
- package/package.json +153 -149
- package/skills/monocart-coverage-reports/SKILL.md +106 -0
- package/skills/monocart-coverage-reports/references/cli.md +108 -0
- package/skills/monocart-coverage-reports/references/collection.md +152 -0
- package/skills/monocart-coverage-reports/references/filtering-and-sourcemaps.md +170 -0
- package/skills/monocart-coverage-reports/references/reports-and-ci.md +219 -0
- package/skills/monocart-coverage-reports/references/repository-map.md +55 -0
- package/lib/index.mjs +0 -9
- package/lib/register/hooks.mjs +0 -3
- package/lib/register/register.mjs +0 -3
package/lib/client/ws-session.js
CHANGED
|
@@ -1,63 +1,141 @@
|
|
|
1
|
-
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
|
|
3
|
+
const parseMessage = (data) => {
|
|
4
|
+
const message = JSON.parse(data);
|
|
5
|
+
if (!message || typeof message !== 'object' || Array.isArray(message)) {
|
|
6
|
+
throw new Error('Expected a CDP message object');
|
|
7
|
+
}
|
|
8
|
+
return message;
|
|
9
|
+
};
|
|
2
10
|
|
|
3
11
|
class WSSession extends EventEmitter {
|
|
4
|
-
constructor(ws) {
|
|
12
|
+
constructor(ws, { timeout = 30000 } = {}) {
|
|
5
13
|
super();
|
|
14
|
+
if (!Number.isFinite(timeout) || timeout < 0) {
|
|
15
|
+
throw new RangeError('WebSocket request timeout must be a non-negative finite number');
|
|
16
|
+
}
|
|
6
17
|
this.ws = ws;
|
|
18
|
+
this.timeout = timeout;
|
|
7
19
|
this.requestId = 1;
|
|
8
20
|
this.requestCache = new Map();
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (id) {
|
|
16
|
-
const request = this.requestCache.get(id);
|
|
17
|
-
this.requestCache.delete(id);
|
|
18
|
-
if (request) {
|
|
19
|
-
request.resolve(message.result);
|
|
20
|
-
}
|
|
21
|
-
return;
|
|
21
|
+
this.events = {
|
|
22
|
+
message: (data) => this.onMessage(data),
|
|
23
|
+
error: (error) => this.disconnect(error),
|
|
24
|
+
close: () => {
|
|
25
|
+
this.disconnect(new Error('WebSocket closed'));
|
|
26
|
+
this.unbind(ws);
|
|
22
27
|
}
|
|
28
|
+
};
|
|
29
|
+
for (const [name, handler] of Object.entries(this.events)) {
|
|
30
|
+
ws.on(name, handler);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
23
33
|
|
|
24
|
-
|
|
25
|
-
|
|
34
|
+
onMessage(data) {
|
|
35
|
+
let message;
|
|
36
|
+
try {
|
|
37
|
+
message = parseMessage(data);
|
|
38
|
+
} catch (cause) {
|
|
39
|
+
this.disconnect(new Error('Invalid WebSocket JSON message', {
|
|
40
|
+
cause
|
|
41
|
+
}));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const { id, method } = message;
|
|
45
|
+
if (id) {
|
|
46
|
+
const pending = this.requestCache.get(id);
|
|
47
|
+
if (!pending) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
let error;
|
|
51
|
+
if (message.error) {
|
|
52
|
+
error = new Error(`Protocol error (${pending.method}): ${message.error.message}`);
|
|
53
|
+
error.code = message.error.code;
|
|
54
|
+
error.data = message.error.data;
|
|
26
55
|
}
|
|
56
|
+
this.settleRequest(id, error, message.result);
|
|
57
|
+
} else if (typeof method === 'string') {
|
|
58
|
+
this.emit(method, message.params, message.sessionId);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
27
61
|
|
|
28
|
-
|
|
62
|
+
settleRequest(id, error, result) {
|
|
63
|
+
const pending = this.requestCache.get(id);
|
|
64
|
+
if (!pending) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
this.requestCache.delete(id);
|
|
68
|
+
clearTimeout(pending.timer);
|
|
69
|
+
if (error) {
|
|
70
|
+
pending.reject(error);
|
|
71
|
+
} else {
|
|
72
|
+
pending.resolve(result);
|
|
73
|
+
}
|
|
29
74
|
}
|
|
30
75
|
|
|
31
76
|
send(method, params) {
|
|
32
77
|
return new Promise((resolve, reject) => {
|
|
33
|
-
|
|
34
|
-
|
|
78
|
+
const ws = this.ws;
|
|
79
|
+
if (!ws || (typeof ws.readyState === 'number' && ws.readyState !== 1)) {
|
|
80
|
+
reject(new Error('Invalid or closed websocket'));
|
|
35
81
|
return;
|
|
36
82
|
}
|
|
37
83
|
const id = this.requestId++;
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
method,
|
|
41
|
-
params: params || {}
|
|
84
|
+
const pending = {
|
|
85
|
+
resolve, reject, method, timer: null
|
|
42
86
|
};
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
87
|
+
// Register before send: a response may arrive before its callback.
|
|
88
|
+
this.requestCache.set(id, pending);
|
|
89
|
+
if (this.timeout > 0) {
|
|
90
|
+
pending.timer = setTimeout(() => {
|
|
91
|
+
const error = new Error(`WebSocket request timed out: ${method}`);
|
|
92
|
+
error.code = 'ETIMEDOUT';
|
|
93
|
+
this.settleRequest(id, error);
|
|
94
|
+
}, this.timeout);
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
ws.send(JSON.stringify({
|
|
98
|
+
id, method, params: params || {}
|
|
99
|
+
}), (error) => {
|
|
100
|
+
if (error) {
|
|
101
|
+
this.settleRequest(id, error);
|
|
102
|
+
}
|
|
50
103
|
});
|
|
51
|
-
})
|
|
104
|
+
} catch (error) {
|
|
105
|
+
this.settleRequest(id, error);
|
|
106
|
+
}
|
|
52
107
|
});
|
|
53
108
|
}
|
|
54
109
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
110
|
+
disconnect(error) {
|
|
111
|
+
const ws = this.ws;
|
|
112
|
+
this.ws = null;
|
|
113
|
+
for (const id of this.requestCache.keys()) {
|
|
114
|
+
this.settleRequest(id, error);
|
|
59
115
|
}
|
|
116
|
+
if (ws) {
|
|
117
|
+
ws.off('message', this.events.message);
|
|
118
|
+
if (ws.readyState === 3) {
|
|
119
|
+
this.unbind(ws);
|
|
120
|
+
} else {
|
|
121
|
+
// Keep error/close handlers until close to consume termination errors.
|
|
122
|
+
ws.terminate();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
unbind(ws) {
|
|
128
|
+
if (this.events) {
|
|
129
|
+
for (const [name, handler] of Object.entries(this.events)) {
|
|
130
|
+
ws.off(name, handler);
|
|
131
|
+
}
|
|
132
|
+
this.events = null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
detach() {
|
|
137
|
+
this.disconnect(new Error('WebSocket detached'));
|
|
60
138
|
}
|
|
61
139
|
}
|
|
62
140
|
|
|
63
|
-
|
|
141
|
+
export { WSSession };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { Util } from '../utils/util.js';
|
|
2
|
+
import { findContainingRange } from './range-index.js';
|
|
2
3
|
|
|
3
4
|
const BranchTypes = {
|
|
4
5
|
ConditionalExpression: 'ConditionalExpression',
|
|
@@ -83,17 +84,14 @@ const getFunctionBlock = (start, end, functionState) => {
|
|
|
83
84
|
return block;
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
const uncoveredBlock =
|
|
87
|
+
const uncoveredBlock = findContainingRange(blockUncoveredRanges, start, end);
|
|
87
88
|
if (uncoveredBlock) {
|
|
88
89
|
return uncoveredBlock;
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
// the block is not exact correct, if there is a block wrapped
|
|
92
93
|
// [x8]{ var a = b || [x4]c }, b is no block, but it can be found in x8 block
|
|
93
|
-
|
|
94
|
-
if (coveredBlocks.length) {
|
|
95
|
-
return coveredBlocks.pop();
|
|
96
|
-
}
|
|
94
|
+
return findContainingRange(blockCoveredRanges, start, end);
|
|
97
95
|
|
|
98
96
|
};
|
|
99
97
|
|
|
@@ -803,7 +801,7 @@ const collectAstInfo = (ast, coverageInfo) => {
|
|
|
803
801
|
|
|
804
802
|
};
|
|
805
803
|
|
|
806
|
-
|
|
804
|
+
export {
|
|
807
805
|
BranchTypes,
|
|
808
806
|
collectAstInfo
|
|
809
807
|
};
|
package/lib/converter/ast.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import * as acorn from 'acorn';
|
|
2
|
+
import * as acornLoose from 'acorn-loose';
|
|
3
|
+
import { parseCss } from '../packages/monocart-coverage-converter.js';
|
|
4
|
+
import { Util } from '../utils/util.js';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
import { collectAstInfo } from './ast-visitor.js';
|
|
7
7
|
|
|
8
8
|
const getCoverageInfo = (coverageList) => {
|
|
9
9
|
const functionMap = new Map();
|
|
@@ -358,7 +358,7 @@ const getCssAstInfo = (item, coverageList) => {
|
|
|
358
358
|
};
|
|
359
359
|
|
|
360
360
|
|
|
361
|
-
|
|
361
|
+
export {
|
|
362
362
|
getJsAstInfo,
|
|
363
363
|
getCssAstInfo
|
|
364
364
|
};
|
|
@@ -1,23 +1,79 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const getSourceMapComments = (source) => {
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import EC from 'eight-colors';
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
|
+
import { Concurrency } from '../platform/concurrency.js';
|
|
6
|
+
import convertSourceMap from 'convert-source-map';
|
|
7
|
+
import { flattenSourceMaps } from './flatten-source-maps.js';
|
|
8
|
+
|
|
9
|
+
import { Util } from '../utils/util.js';
|
|
10
|
+
|
|
11
|
+
const getSourceMapCandidates = (source) => {
|
|
13
12
|
if (!source.includes('sourceMappingURL=')) {
|
|
14
13
|
return [];
|
|
15
14
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
|
|
16
|
+
// Match directive-shaped text without parsing JS; valid maps in strings can be selected.
|
|
17
|
+
const candidates = [];
|
|
18
|
+
for (const match of source.matchAll(convertSourceMap.commentRegex)) {
|
|
19
|
+
candidates.push({
|
|
20
|
+
index: match.index,
|
|
21
|
+
comment: match[0],
|
|
22
|
+
inline: true
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
for (const match of source.matchAll(convertSourceMap.mapFileCommentRegex)) {
|
|
26
|
+
const filename = match[1] || match[2];
|
|
27
|
+
if (filename && !filename.startsWith('data:')) {
|
|
28
|
+
candidates.push({
|
|
29
|
+
index: match.index,
|
|
30
|
+
filename
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Like 2.13.0, try inline maps before external ones. Within each kind,
|
|
35
|
+
// start at the last directive and fall back when it is unusable.
|
|
36
|
+
return candidates.sort((a, b) => {
|
|
37
|
+
if (a.inline !== b.inline) {
|
|
38
|
+
return a.inline ? -1 : 1;
|
|
39
|
+
}
|
|
40
|
+
return b.index - a.index;
|
|
41
|
+
});
|
|
19
42
|
};
|
|
20
43
|
|
|
44
|
+
// Only check the fields required to resolve a map; decoding is deferred to
|
|
45
|
+
// the downstream converter. A map without sources cannot map to original code.
|
|
46
|
+
const isValidBasicMap = (data) => Array.isArray(data.sources)
|
|
47
|
+
&& data.sources.every((source) => typeof source === 'string')
|
|
48
|
+
&& typeof data.mappings === 'string'
|
|
49
|
+
&& (data.sources.length > 0 || data.mappings === '');
|
|
50
|
+
|
|
51
|
+
const isValidSection = (section) => section && section.offset
|
|
52
|
+
&& Number.isInteger(section.offset.line) && section.offset.line >= 0
|
|
53
|
+
&& Number.isInteger(section.offset.column) && section.offset.column >= 0
|
|
54
|
+
&& isValidSourceMap(section.map);
|
|
55
|
+
|
|
56
|
+
const isValidSourceMap = (data) => {
|
|
57
|
+
if (!data || typeof data !== 'object' || Array.isArray(data)) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
if (Array.isArray(data.sections)) {
|
|
61
|
+
return data.sections.every(isValidSection);
|
|
62
|
+
}
|
|
63
|
+
return isValidBasicMap(data);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// An empty map cannot map coverage to any original source. Try the next
|
|
67
|
+
// candidate instead, including when an indexed map has only empty sections.
|
|
68
|
+
const hasMappings = (data) => {
|
|
69
|
+
if (Array.isArray(data.sections)) {
|
|
70
|
+
return data.sections.some((section) => hasMappings(section.map));
|
|
71
|
+
}
|
|
72
|
+
return data.mappings.length > 0;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const isUsableSourceMap = (data) => isValidSourceMap(data) && hasMappings(data);
|
|
76
|
+
|
|
21
77
|
const defaultSourceMapResolver = async (url = '') => {
|
|
22
78
|
|
|
23
79
|
if (url.startsWith('file:')) {
|
|
@@ -63,24 +119,6 @@ const resolveMapUrl = (filename, url) => {
|
|
|
63
119
|
return urlObj?.toString();
|
|
64
120
|
};
|
|
65
121
|
|
|
66
|
-
const getSourceMapUrl = (comments, url) => {
|
|
67
|
-
for (let i = comments.length - 1; i >= 0; i--) {
|
|
68
|
-
const r = convertSourceMap.mapFileCommentRegex.exec(comments[i]);
|
|
69
|
-
if (!r || r.index !== 0) {
|
|
70
|
-
continue;
|
|
71
|
-
}
|
|
72
|
-
// //# captures in 1 and /* */ in 2
|
|
73
|
-
const filename = r[1] || r[2];
|
|
74
|
-
if (!filename || filename.startsWith('data:')) {
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
const mapUrl = resolveMapUrl(filename, url);
|
|
78
|
-
if (mapUrl) {
|
|
79
|
-
return mapUrl;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
|
|
84
122
|
const resolveSourcesContent = (data, url) => {
|
|
85
123
|
|
|
86
124
|
const { sources, sourcesContent } = data;
|
|
@@ -125,7 +163,7 @@ const resolveSourcesContent = (data, url) => {
|
|
|
125
163
|
const checkSourcesContent = (data) => {
|
|
126
164
|
const { sourcesContent, sources } = data;
|
|
127
165
|
|
|
128
|
-
if (!sourcesContent) {
|
|
166
|
+
if (!Array.isArray(sourcesContent)) {
|
|
129
167
|
data.sourcesContent = [];
|
|
130
168
|
return false;
|
|
131
169
|
}
|
|
@@ -146,15 +184,7 @@ const resolveSectionedSourceMap = (data, url, sections) => {
|
|
|
146
184
|
// offset: { line: 1, column: 0 },
|
|
147
185
|
// map: { sources, sourcesContent }
|
|
148
186
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (checkSourcesContent(map)) {
|
|
152
|
-
hasSourceContent = true;
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const done = resolveSourcesContent(map, url);
|
|
157
|
-
if (done) {
|
|
187
|
+
if (resolveSourceMap(item.map, url)) {
|
|
158
188
|
hasSourceContent = true;
|
|
159
189
|
}
|
|
160
190
|
|
|
@@ -169,6 +199,10 @@ const resolveSourceMap = (data, url) => {
|
|
|
169
199
|
if (!data) {
|
|
170
200
|
return;
|
|
171
201
|
}
|
|
202
|
+
// Optional metadata may be absent or malformed in otherwise usable maps.
|
|
203
|
+
if (!Array.isArray(data.names)) {
|
|
204
|
+
data.names = [];
|
|
205
|
+
}
|
|
172
206
|
const {
|
|
173
207
|
sections, sources, mappings
|
|
174
208
|
} = data;
|
|
@@ -177,7 +211,7 @@ const resolveSourceMap = (data, url) => {
|
|
|
177
211
|
return resolveSectionedSourceMap(data, url, sections);
|
|
178
212
|
}
|
|
179
213
|
|
|
180
|
-
if (!sources ||
|
|
214
|
+
if (!Array.isArray(sources) || typeof mappings !== 'string') {
|
|
181
215
|
return;
|
|
182
216
|
}
|
|
183
217
|
|
|
@@ -191,21 +225,6 @@ const resolveSourceMap = (data, url) => {
|
|
|
191
225
|
|
|
192
226
|
};
|
|
193
227
|
|
|
194
|
-
const getInlineSourceMap = (comments) => {
|
|
195
|
-
for (let i = comments.length - 1; i >= 0; i--) {
|
|
196
|
-
const comment = comments[i];
|
|
197
|
-
const match = convertSourceMap.commentRegex.exec(comment);
|
|
198
|
-
if (!match || match.index !== 0) {
|
|
199
|
-
continue;
|
|
200
|
-
}
|
|
201
|
-
try {
|
|
202
|
-
return convertSourceMap.fromComment(comment);
|
|
203
|
-
} catch (e) {
|
|
204
|
-
// Ignore invalid inline maps.
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
|
|
209
228
|
const collectSourceMaps = async (v8list, options) => {
|
|
210
229
|
|
|
211
230
|
const sourceList = [];
|
|
@@ -237,52 +256,60 @@ const collectSourceMaps = async (v8list, options) => {
|
|
|
237
256
|
sourceMap
|
|
238
257
|
};
|
|
239
258
|
|
|
259
|
+
// An explicitly supplied, usable map takes precedence over sourceMappingURL.
|
|
240
260
|
// Keep the original source so V8 offsets remain valid.
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
const smc = getInlineSourceMap(comments);
|
|
246
|
-
if (smc) {
|
|
247
|
-
sourceData.sourceMap = resolveSourceMap(smc.sourcemap, url);
|
|
248
|
-
sourcemapList.push({
|
|
249
|
-
url,
|
|
250
|
-
inline: true
|
|
251
|
-
});
|
|
252
|
-
sourceList.push(sourceData);
|
|
253
|
-
continue;
|
|
254
|
-
}
|
|
255
|
-
// from url async
|
|
256
|
-
const sourceMapUrl = getSourceMapUrl(comments, url);
|
|
257
|
-
if (sourceMapUrl) {
|
|
261
|
+
if (type === 'js' && !isUsableSourceMap(sourceData.sourceMap)) {
|
|
262
|
+
delete sourceData.sourceMap;
|
|
263
|
+
const candidates = getSourceMapCandidates(source);
|
|
264
|
+
if (candidates.length) {
|
|
258
265
|
concurrency.addItem({
|
|
259
|
-
|
|
266
|
+
candidates,
|
|
260
267
|
sourceData
|
|
261
268
|
});
|
|
262
|
-
continue;
|
|
263
269
|
}
|
|
264
270
|
}
|
|
265
271
|
|
|
266
|
-
//
|
|
272
|
+
// Keep source entries in input order while maps load concurrently.
|
|
267
273
|
sourceList.push(sourceData);
|
|
268
274
|
|
|
269
275
|
}
|
|
270
276
|
|
|
271
|
-
// from url concurrency
|
|
272
277
|
await concurrency.start(async (item) => {
|
|
273
|
-
const {
|
|
278
|
+
const { candidates, sourceData } = item;
|
|
274
279
|
const { url } = sourceData;
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
280
|
+
for (const candidate of candidates) {
|
|
281
|
+
let data;
|
|
282
|
+
let sourceMapUrl;
|
|
283
|
+
try {
|
|
284
|
+
if (candidate.inline) {
|
|
285
|
+
data = convertSourceMap.fromComment(candidate.comment).sourcemap;
|
|
286
|
+
} else {
|
|
287
|
+
sourceMapUrl = resolveMapUrl(candidate.filename, url);
|
|
288
|
+
if (!sourceMapUrl) {
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
data = await loadSourceMap(sourceMapUrl, options);
|
|
292
|
+
}
|
|
293
|
+
if (!isUsableSourceMap(data)) {
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
const sourceMap = resolveSourceMap(data, url);
|
|
297
|
+
if (!sourceMap) {
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
sourceData.sourceMap = sourceMap;
|
|
301
|
+
sourcemapList.push(candidate.inline ? {
|
|
302
|
+
url,
|
|
303
|
+
inline: true
|
|
304
|
+
} : {
|
|
305
|
+
url,
|
|
306
|
+
sourceMapUrl
|
|
307
|
+
});
|
|
308
|
+
break;
|
|
309
|
+
} catch (e) {
|
|
310
|
+
// Try an earlier sourceMappingURL if parsing or loading fails.
|
|
311
|
+
}
|
|
282
312
|
}
|
|
283
|
-
|
|
284
|
-
sourceList.push(sourceData);
|
|
285
|
-
|
|
286
313
|
});
|
|
287
314
|
|
|
288
315
|
return {
|
|
@@ -292,7 +319,7 @@ const collectSourceMaps = async (v8list, options) => {
|
|
|
292
319
|
|
|
293
320
|
};
|
|
294
321
|
|
|
295
|
-
|
|
322
|
+
export {
|
|
296
323
|
collectSourceMaps,
|
|
297
324
|
resolveSourceMap
|
|
298
325
|
};
|