<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <base data-ice="baseUrl" href="../../../">
  <title data-ice="title">js/lib/PackageImporter.js | API Document</title>
  <link type="text/css" rel="stylesheet" href="css/style.css">
  <link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css">
  <script src="script/prettify/prettify.js"></script>
  
  
  <script src="script/manual.js"></script>
</head>
<body class="layout-container" data-ice="rootContainer">

<header>
  <a href="./">Home</a>
  
  <a href="identifiers.html">Reference</a>
  <a href="source.html">Source</a>
  <a href="test.html" data-ice="testLink">Test</a>
  <a data-ice="repoURL" href="https://github.com/maoberlehner/node-sass-package-importer" class="repo-url-github">Repository</a>
  <div class="search-box">
  <span>
    <img src="./image/search.png">
    <span class="search-input-edge"></span><input class="search-input"><span class="search-input-edge"></span>
  </span>
    <ul class="search-result"></ul>
  </div>
</header>

<nav class="navigation" data-ice="nav"><div>
  <ul>
    
  <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-index">index</a></span></span></li>
<li data-ice="doc"><div data-ice="dirPath" class="nav-dir-path">lib</div><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/js/lib/PackageImporter.js~PackageImporter.html">PackageImporter</a></span></span></li>
</ul>
</div>
</nav>

<div class="content" data-ice="content"><h1 data-ice="title">js/lib/PackageImporter.js</h1>
<pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">import resolve from &apos;resolve&apos;;
import path from &apos;path&apos;;

/**
 * Import packages from the `node_modules` directory.
 */
export default class PackageImporter {
  /**
   * @param {Object} options - Configuration options.
   */
  constructor(options = {}) {
    const defaultOptions = {
      cwd: process.cwd(),
      extensions: [
        &apos;.scss&apos;,
        &apos;.sass&apos;
      ],
      packageKeys: [
        &apos;sass&apos;,
        &apos;scss&apos;,
        &apos;style&apos;,
        &apos;css&apos;,
        &apos;main.sass&apos;,
        &apos;main.scss&apos;,
        &apos;main.style&apos;,
        &apos;main.css&apos;,
        &apos;main&apos;
      ]
    };
    /** @type {Object} */
    this.options = Object.assign({}, defaultOptions, options);
  }

  /**
   * Synchronously resolve the path to a node-sass import url.
   * @param {string} url - Import url from node-sass.
   * @return {string} Fully resolved import url or null.
   */
  resolveSync(url) {
    const cleanUrl = this.cleanUrl(url);
    const urlVariants = this.urlVariants(cleanUrl);
    let file = null;
    // Find a url variant that can be resolved.
    urlVariants.some(urlVariant =&gt; {
      try {
        const resolvedPath = resolve.sync(urlVariant, {
          basedir: this.options.cwd,
          packageFilter: pkg =&gt; this.resolveFilter(pkg),
          extensions: this.options.extensions
        });
        if (resolvedPath) {
          file = resolvedPath;
          return true;
        }
      } catch (e) {}
      return false;
    });
    return file;
  }

  /**
   * Asynchronously resolve the path to a node-sass import url.
   * @param {string} url - Import url from node-sass.
   * @return {Promise} Promise for a fully resolved import url.
   */
  resolve(url) {
    return new Promise((promiseResolve) =&gt; {
      promiseResolve(this.resolveSync(url));
    });
  }

  /**
   * Clean a node sass import url.
   * @param {string} url - Import url from node-sass.
   * @return {string} Cleaned url.
   */
  cleanUrl(url) {
    // Remove tilde symbol from the beginning
    // of urls (except home &quot;~/&quot; directory).
    const re = new RegExp(`^~(?!${path.sep})`);
    return url.replace(re, &apos;&apos;);
  }

  /**
   * Create url variants for partial file matching (e.g. _file.scss).
   * @param {string} url - Import url from node-sass.
   * @return {Array} Multiple variants of sass file names.
   */
  urlVariants(url) {
    const parsedUrl = path.parse(url);
    let urlVariants = [url];
    if (parsedUrl.dir &amp;&amp; !parsedUrl.ext) {
      urlVariants = this.options.extensions.reduce((x, extension) =&gt; {
        x.push(path.join(parsedUrl.dir, `${parsedUrl.name}${extension}`));
        x.push(path.join(parsedUrl.dir, `_${parsedUrl.name}${extension}`));
        return x;
      }, urlVariants);
    }
    return urlVariants;
  }

  /**
   * Find the first matching key in a package.json file
   * and set it as value for the `main` field.
   * @param  {Object} pkg - Contents of a package.json.
   * @return {Object} A package.json object with a replaced main value.
   */
  resolveFilter(pkg) {
    const newPkg = pkg;
    const pkgKey = this.options.packageKeys.find(x =&gt; pkg[x] !== undefined);
    newPkg.main = pkg[pkgKey];
    return newPkg;
  }
}
</code></pre>

</div>

<footer class="footer">
  Generated by <a href="https://esdoc.org">ESDoc<span data-ice="esdocVersion">(0.4.8)</span></a>
</footer>

<script src="script/search_index.js"></script>
<script src="script/search.js"></script>
<script src="script/pretty-print.js"></script>
<script src="script/inherited-summary.js"></script>
<script src="script/test-summary.js"></script>
<script src="script/inner-link.js"></script>
<script src="script/patch-for-local.js"></script>
</body>
</html>