monocart-reporter 1.6.33 → 1.6.35

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.
@@ -14,18 +14,31 @@ const {
14
14
  convertSourceMap
15
15
  } = require('../../../runtime/monocart-coverage.js');
16
16
 
17
+ const { initSourceMapRootAndUrl } = require('../coverage-utils.js');
18
+
17
19
  // const V8toIstanbul = require('v8-to-istanbul');
18
20
  // const istanbulLibCoverage = require('istanbul-lib-coverage');
19
21
  // const istanbulLibReport = require('istanbul-lib-report');
20
22
 
21
- const {
22
- getSourcePath, mergeSourceRoot, collectSourceMaps
23
- } = require('../coverage-utils.js');
23
+ const saveIstanbulReport = (coverageData, fileSources, options) => {
24
24
 
25
+ // source path handler
26
+ let data = coverageData;
27
+ if (typeof options.sourcePath === 'function') {
28
+ data = {};
29
+ Object.keys(coverageData).forEach((sourcePath) => {
30
+ const d = coverageData[sourcePath];
31
+ const newSourcePath = options.sourcePath(sourcePath, fileSources);
32
+ if (newSourcePath) {
33
+ sourcePath = newSourcePath;
34
+ }
35
+ d.path = sourcePath;
36
+ data[sourcePath] = d;
37
+ });
38
+ }
25
39
 
26
- const saveIstanbulReport = (coverageData, fileSources, options) => {
27
40
 
28
- const coverageMap = istanbulLibCoverage.createCoverageMap(coverageData);
41
+ const coverageMap = istanbulLibCoverage.createCoverageMap(data);
29
42
 
30
43
  // https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-lib-report
31
44
  const contextOptions = {
@@ -99,46 +112,15 @@ const saveIstanbulReport = (coverageData, fileSources, options) => {
99
112
 
100
113
  // ===================================================================================================
101
114
 
102
- const initIstanbulV8List = async (v8list, options) => {
103
-
104
- // filter list
105
- const entryFilter = options.entryFilter;
106
- if (typeof entryFilter === 'function') {
107
- v8list = v8list.filter(entryFilter);
108
- }
109
-
110
- // only js with source (without css)
111
- v8list = v8list.filter((item) => {
112
- if (typeof item.source === 'string' && item.functions) {
113
- return true;
114
- }
115
- });
116
-
117
- // collect source maps
118
- if (options.unpackSourceMap) {
119
- await collectSourceMaps(v8list);
120
- }
121
-
122
- // init list properties
123
- v8list.forEach((item, i) => {
124
- const sourcePath = getSourcePath(item.url, i + 1, 'js');
125
- const filename = path.basename(sourcePath);
126
- item.filename = filename;
127
- item.sourcePath = sourcePath;
128
- // console.log(sourcePath);
129
- });
130
-
131
- return v8list;
132
- };
133
-
134
115
  const getConversionSources = (item, fileSources) => {
116
+
135
117
  const { source, sourceMap } = item;
136
118
 
137
119
  fileSources[item.sourcePath] = source;
138
120
 
139
121
  const sources = {
140
122
  // remove map file
141
- source: convertSourceMap.removeMapFileComments(source)
123
+ source: convertSourceMap.removeComments(source)
142
124
  };
143
125
 
144
126
  if (!sourceMap) {
@@ -151,17 +133,8 @@ const getConversionSources = (item, fileSources) => {
151
133
  // 'webpack://monocart-v8/external umd "monocart-code-viewer"'
152
134
  // format the url to sourcePath
153
135
 
154
- // reset sourceRoot
155
- const sourceRoot = sourceMap.sourceRoot || '';
156
- sourceMap.sourceRoot = '';
157
-
158
- // resolve source path and add to file sources cache for html report sourceFinder
159
- sourceMap.sources = sourceMap.sources.map((sourceName, i) => {
160
- const sourceUrl = mergeSourceRoot(sourceRoot, sourceName);
161
- const newSourceName = getSourcePath(sourceUrl, i + 1);
162
- fileSources[newSourceName] = sourceMap.sourcesContent[i];
163
- return newSourceName;
164
- });
136
+ const fileUrls = {};
137
+ initSourceMapRootAndUrl(sourceMap, fileUrls, fileSources);
165
138
 
166
139
  // console.log(sourceMap.sources);
167
140
 
@@ -177,7 +150,8 @@ const convertV8ToIstanbul = async (v8list, options) => {
177
150
 
178
151
  // console.log('v8list before', v8list.map((it) => it.url));
179
152
 
180
- v8list = await initIstanbulV8List(v8list, options);
153
+ // only js with source (without css)
154
+ v8list = v8list.filter((item) => item.type === 'js');
181
155
 
182
156
  // console.log('v8list after', v8list.map((it) => it.url));
183
157
  // console.log('has map', v8list.filter((it) => it.sourceMap));
@@ -226,7 +200,7 @@ const convertV8ToIstanbul = async (v8list, options) => {
226
200
 
227
201
  const coverageData = coverageMap.toJSON();
228
202
 
229
- // console.log('convertV8ToIstanbul coverageData', Object.keys(coverageData));
203
+ // console.log('coverageData', Object.keys(coverageData));
230
204
 
231
205
  return {
232
206
  coverageData,
@@ -71,35 +71,26 @@ const dedupeCountRanges = (ranges) => {
71
71
 
72
72
  sortRanges(ranges);
73
73
 
74
+ let hasDedupe = false;
75
+
74
76
  // merge count for same range
75
77
  ranges.reduce((lastRange, range) => {
76
78
  if (range.start === lastRange.start && range.end === lastRange.end) {
77
79
  range.dedupe = true;
78
80
  lastRange.count += range.count;
81
+
82
+ hasDedupe = true;
83
+
79
84
  return lastRange;
80
85
  }
81
86
  return range;
82
87
  });
83
88
 
84
- ranges = ranges.filter((it) => !it.dedupe);
85
-
86
- // console.log('ranges length before', ranges.length);
87
-
88
- // connect uncovered ranges (count = 0)
89
- const coveredRanges = [];
90
- const uncoveredRanges = [];
91
- for (const range of ranges) {
92
- if (range.count > 0) {
93
- coveredRanges.push(range);
94
- } else {
95
- uncoveredRanges.push(range);
96
- }
89
+ if (hasDedupe) {
90
+ // console.log(ranges);
91
+ ranges = ranges.filter((it) => !it.dedupe);
97
92
  }
98
93
 
99
- ranges = [].concat(dedupeRanges(uncoveredRanges)).concat(coveredRanges);
100
-
101
- sortRanges(ranges);
102
-
103
94
  // console.log('ranges length after', ranges.length);
104
95
 
105
96
  return ranges;
@@ -1,12 +1,16 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
1
3
  const EC = require('eight-colors');
2
4
 
3
5
  const { SourceMapConsumer } = require('source-map');
4
6
 
5
7
  const PositionMapping = require('./position-mapping.js');
6
8
  const { dedupeCountRanges } = require('./dedupe.js');
7
- const {
8
- getSourcePath, mergeSourceRoot, collectSourceMaps
9
- } = require('../coverage-utils.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');
10
14
 
11
15
  // SourceMapConsumer.GREATEST_LOWER_BOUND = 1;
12
16
  // SourceMapConsumer.LEAST_UPPER_BOUND = 2;
@@ -134,6 +138,7 @@ const addOriginalRange = (originalMapping, start, end, count) => {
134
138
 
135
139
  // =========================================================================================================
136
140
 
141
+
137
142
  const unpackJsSourceMap = async (item, v8list, options) => {
138
143
  // console.log('------------------------------------------------------');
139
144
  // console.log(item.type, item.url);
@@ -141,17 +146,9 @@ const unpackJsSourceMap = async (item, v8list, options) => {
141
146
 
142
147
  const sourceMap = item.sourceMap;
143
148
 
144
- // reset sourceRoot
145
- const sourceRoot = sourceMap.sourceRoot || '';
146
- sourceMap.sourceRoot = '';
147
-
148
- const urlMap = {};
149
- sourceMap.sources = sourceMap.sources.map((sourceName, i) => {
150
- const sourceUrl = mergeSourceRoot(sourceRoot, sourceName);
151
- const newSourceName = getSourcePath(sourceUrl, i + 1);
152
- urlMap[newSourceName] = sourceUrl;
153
- return newSourceName;
154
- });
149
+ const fileUrls = {};
150
+ const fileSources = {};
151
+ initSourceMapRootAndUrl(sourceMap, fileUrls, fileSources);
155
152
 
156
153
  const generatedMapping = new PositionMapping(item.source);
157
154
  const consumer = await new SourceMapConsumer(sourceMap);
@@ -216,18 +213,34 @@ const unpackJsSourceMap = async (item, v8list, options) => {
216
213
  // append to v8list
217
214
  originalMappings.forEach((originalMapping, currentSource) => {
218
215
 
219
- const url = urlMap[currentSource] || currentSource;
216
+ const url = fileUrls[currentSource] || currentSource;
220
217
  const ranges = dedupeCountRanges(originalMapping.ranges);
221
218
 
222
219
  // console.log('add source url', url);
223
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
+
224
236
  v8list.push({
225
237
  url,
226
- type: item.type,
238
+ id,
239
+ type,
227
240
  sourcePath: currentSource,
228
241
  distFile: item.sourceMap.file,
229
242
  ranges,
230
- source: originalMapping.source
243
+ source
231
244
  });
232
245
 
233
246
  });
@@ -235,6 +248,160 @@ const unpackJsSourceMap = async (item, v8list, options) => {
235
248
 
236
249
  // =========================================================================================================
237
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 (!options.unpackSourceMap) {
392
+ return;
393
+ }
394
+
395
+ if (inlineSourceMap) {
396
+ await collectInlineSourceMaps(v8list);
397
+ return;
398
+ }
399
+
400
+ await collectFileSourceMaps(v8list, options);
401
+
402
+ };
403
+
404
+ // =========================================================================================================
238
405
  const filterSourceMapList = (v8list, options) => {
239
406
  const sourceMapList = [];
240
407
  const indexes = [];
@@ -262,16 +429,14 @@ const filterSourceMapList = (v8list, options) => {
262
429
  return sourceMapList;
263
430
  };
264
431
 
432
+ // requires ranges before unpack
265
433
  const unpackSourceMaps = async (v8list, options) => {
266
434
 
435
+ // collect source maps
267
436
  if (!options.unpackSourceMap) {
268
437
  return;
269
438
  }
270
439
 
271
- // console.log(v8list.map((it) => it.url).join(', '));
272
-
273
- await collectSourceMaps(v8list);
274
-
275
440
  const sourceMapList = filterSourceMapList(v8list, options);
276
441
  if (!sourceMapList) {
277
442
  // nothing to unpack
@@ -288,5 +453,6 @@ const unpackSourceMaps = async (v8list, options) => {
288
453
 
289
454
 
290
455
  module.exports = {
456
+ collectSourceMaps,
291
457
  unpackSourceMaps
292
458
  };