Code coverage report for src/index.js

Statements: 98.55% (68 / 69)      Branches: 85.71% (24 / 28)      Functions: 80% (4 / 5)      Lines: 97.56% (40 / 41)      Ignored: 1 statement, 1 branch     

All files » src/ » index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108                              1 1   1 1   1 1 1                     1   10 10   10 10   10   10 10 3     7   7 7       7 7       7 7                     1 22 22   22         22 22 1     21 21   21     21   21   21   21       21     1  
import hook from './hook';
import { readFileSync } from 'fs';
import { dirname, sep, relative, resolve } from 'path';
import { get, removeQuotes } from './utility';
import assign from 'lodash.assign';
import identity from 'lodash.identity';
import pick from 'lodash.pick';
import postcss from 'postcss';
 
import ExtractImports from 'postcss-modules-extract-imports';
import LocalByDefault from 'postcss-modules-local-by-default';
import Scope from 'postcss-modules-scope';
import Parser from './parser';
 
// cache
let importNr = 0;
let tokensByFile = {};
// processing functions
const preProcess = identity;
let postProcess;
// defaults
let lazyResultOpts = {};
let plugins = [LocalByDefault, ExtractImports, Scope];
let rootDir = process.cwd();
 
/**
 * @param  {object}   opts
 * @param  {function} opts.createImportedName
 * @param  {function} opts.generateScopedName
 * @param  {function} opts.processCss
 * @param  {string}   opts.rootDir
 * @param  {string}   opts.to
 * @param  {array}    opts.use
 */
export default function setup(opts = {}) {
  // clearing cache
  importNr = 0;
  tokensByFile = {};
 
  postProcess = get('processCss', null, 'function', opts) || null;
  rootDir = get('rootDir', ['root', 'd'], 'string', opts) || process.cwd();
  // https://github.com/postcss/postcss/blob/master/docs/api.md#processorprocesscss-opts
  lazyResultOpts = pick(opts, ['to']);
 
  const customPlugins = get('use', ['u'], 'array', opts);
  if (customPlugins) {
    return void (plugins = customPlugins);
  }
 
  plugins = [];
 
  const mode = get('mode', null, 'string', opts);
  plugins.push(mode
    ? new LocalByDefault({mode: opts.mode})
    : LocalByDefault);
 
  const createImportedName = get('createImportedName', null, 'function', opts);
  plugins.push(createImportedName
    ? new ExtractImports({createImportedName: opts.createImportedName})
    : ExtractImports);
 
  const generateScopedName = get('generateScopedName', null, 'function', opts);
  plugins.push(generateScopedName
    ? new Scope({generateScopedName: opts.generateScopedName})
    : Scope);
}
 
/**
 * @param  {string} _to    Absolute or relative path. Also can be path to the Node.JS module.
 * @param  {string} _from  Absolute path (relative to root).
 * @param  {string} _trace
 * @return {object}
 */
function fetch(_to, _from, _trace) {
  const trace = _trace || String.fromCharCode(importNr++);
  const newPath = removeQuotes(_to);
  // getting absolute path to the processing file
  const filename = /\w/.test(newPath[0])
    ? require.resolve(newPath)
    : resolve(dirname(_from), newPath);
 
  // checking cache
  let tokens = tokensByFile[filename];
  if (tokens) {
    return tokens;
  }
 
  const rootRelativePath = sep + relative(rootDir, filename);
  const CSSSource = preProcess(readFileSync(filename, 'utf8'));
 
  const lazyResult = postcss(plugins.concat(new Parser({ fetch, filename, trace })))
    .process(CSSSource, assign(lazyResultOpts, {from: rootRelativePath}));
 
  lazyResult.warnings().forEach(message => console.warn(message.text));
 
  tokens = lazyResult.root.tokens;
  // updating cache
  tokensByFile[filename] = tokens;
 
  Iif (postProcess) {
    postProcess(lazyResult.css);
  }
 
  return tokens;
}
 
hook(filename => fetch(filename, filename));