index.js
1 "use strict"; 2 3 Object.defineProperty(exports, "__esModule", { 4 value: true 5 }); 6 exports.default = void 0; 7 8 var _path = _interopRequireDefault(require("path")); 9 10 var _fs = require("fs"); 11 12 var _child_process = require("child_process"); 13 14 var _helperPluginUtils = require("@babel/helper-plugin-utils"); 15 16 var _istanbulLibInstrument = require("istanbul-lib-instrument"); 17 18 var _testExclude = _interopRequireDefault(require("test-exclude")); 19 20 var _schema = _interopRequireDefault(require("@istanbuljs/schema")); 21 22 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 23 24 function getRealpath(n) { 25 try { 26 return (0, _fs.realpathSync)(n) || 27 /* istanbul ignore next */ 28 n; 29 } catch (e) { 30 /* istanbul ignore next */ 31 return n; 32 } 33 } 34 35 const memoize = new Map(); 36 /* istanbul ignore next */ 37 38 const memosep = _path.default.sep === '/' ? ':' : ';'; 39 40 function loadNycConfig(cwd, opts) { 41 let memokey = cwd; 42 const args = [_path.default.resolve(__dirname, 'load-nyc-config-sync.js'), cwd]; 43 44 if ('nycrcPath' in opts) { 45 args.push(opts.nycrcPath); 46 memokey += memosep + opts.nycrcPath; 47 } 48 /* execFileSync is expensive, avoid it if possible! */ 49 50 51 if (memoize.has(memokey)) { 52 return memoize.get(memokey); 53 } 54 55 const result = JSON.parse((0, _child_process.execFileSync)(process.execPath, args)); 56 const error = result['load-nyc-config-sync-error']; 57 58 if (error) { 59 throw new Error(error); 60 } 61 62 const config = { ..._schema.default.defaults.babelPluginIstanbul, 63 cwd, 64 ...result 65 }; 66 memoize.set(memokey, config); 67 return config; 68 } 69 70 function findConfig(opts) { 71 const cwd = getRealpath(opts.cwd || process.env.NYC_CWD || 72 /* istanbul ignore next */ 73 process.cwd()); 74 const keys = Object.keys(opts); 75 const ignored = Object.keys(opts).filter(s => s === 'nycrcPath' || s === 'cwd'); 76 77 if (keys.length > ignored.length) { 78 // explicitly configuring options in babel 79 // takes precedence. 80 return { ..._schema.default.defaults.babelPluginIstanbul, 81 cwd, 82 ...opts 83 }; 84 } 85 86 if (ignored.length === 0 && process.env.NYC_CONFIG) { 87 // defaults were already applied by nyc 88 return JSON.parse(process.env.NYC_CONFIG); 89 } 90 91 return loadNycConfig(cwd, opts); 92 } 93 94 function makeShouldSkip() { 95 let exclude; 96 return function shouldSkip(file, nycConfig) { 97 if (!exclude || exclude.cwd !== nycConfig.cwd) { 98 exclude = new _testExclude.default({ 99 cwd: nycConfig.cwd, 100 include: nycConfig.include, 101 exclude: nycConfig.exclude, 102 extension: nycConfig.extension, 103 // Make sure this is true unless explicitly set to `false`. `undefined` is still `true`. 104 excludeNodeModules: nycConfig.excludeNodeModules !== false 105 }); 106 } 107 108 return !exclude.shouldInstrument(file); 109 }; 110 } 111 112 var _default = (0, _helperPluginUtils.declare)(api => { 113 api.assertVersion(7); 114 const shouldSkip = makeShouldSkip(); 115 const t = api.types; 116 return { 117 visitor: { 118 Program: { 119 enter(path) { 120 this.__dv__ = null; 121 this.nycConfig = findConfig(this.opts); 122 const realPath = getRealpath(this.file.opts.filename); 123 124 if (shouldSkip(realPath, this.nycConfig)) { 125 return; 126 } 127 128 let { 129 inputSourceMap 130 } = this.opts; 131 132 if (this.opts.useInlineSourceMaps !== false) { 133 if (!inputSourceMap && this.file.inputMap) { 134 inputSourceMap = this.file.inputMap.sourcemap; 135 } 136 } 137 138 const visitorOptions = {}; 139 Object.entries(_schema.default.defaults.instrumentVisitor).forEach(([name, defaultValue]) => { 140 if (name in this.nycConfig) { 141 visitorOptions[name] = this.nycConfig[name]; 142 } else { 143 visitorOptions[name] = _schema.default.defaults.instrumentVisitor[name]; 144 } 145 }); 146 this.__dv__ = (0, _istanbulLibInstrument.programVisitor)(t, realPath, { ...visitorOptions, 147 inputSourceMap 148 }); 149 150 this.__dv__.enter(path); 151 }, 152 153 exit(path) { 154 if (!this.__dv__) { 155 return; 156 } 157 158 const result = this.__dv__.exit(path); 159 160 if (this.opts.onCover) { 161 this.opts.onCover(getRealpath(this.file.opts.filename), result.fileCoverage); 162 } 163 } 164 165 } 166 } 167 }; 168 }); 169 170 exports.default = _default;