"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.transformModern = transformModern;
function _path() {
  const data = _interopRequireWildcard(require("path"));
  _path = function () {
    return data;
  };
  return data;
}
function _sourceMap() {
  const data = _interopRequireDefault(require("@parcel/source-map"));
  _sourceMap = function () {
    return data;
  };
  return data;
}
function _sass() {
  const data = _interopRequireDefault(require("sass"));
  _sass = function () {
    return data;
  };
  return data;
}
function _url() {
  const data = require("url");
  _url = function () {
    return data;
  };
  return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
// E.g: ~library/file.sass
const NODE_MODULE_ALIAS_RE = /^~[^/\\]/;
async function transformModern(asset, config, resolve, options) {
  let rawConfig = config ?? {};
  let css;
  try {
    let code = await asset.getCode();
    let indentedSyntax = rawConfig.syntax === 'indented' || typeof rawConfig.indentedSyntax === 'boolean' ? rawConfig.indentedSyntax : undefined;
    let result = await _sass().default.compileStringAsync(code, {
      ...rawConfig,
      loadPaths: undefined,
      url: (0, _url().pathToFileURL)(asset.filePath),
      importers: [...(rawConfig.importers || []), resolvePathImporter({
        asset,
        resolve,
        loadPaths: rawConfig.loadPaths,
        indentedSyntax,
        options
      })],
      syntax: (indentedSyntax != null ? indentedSyntax : asset.type === 'sass') ? 'indented' : 'scss',
      sourceMap: !!asset.env.sourceMap
    });
    css = result.css;
    for (let included of result.loadedUrls) {
      let file = (0, _url().fileURLToPath)(included);
      if (file !== asset.filePath) {
        asset.invalidateOnFileChange(file);
      }
    }
    if (result.sourceMap != null) {
      let map = new (_sourceMap().default)(options.projectRoot);
      map.addVLQMap(result.sourceMap);
      asset.setMap(map);
    }
  } catch (err) {
    // Adapt the Error object for the reporter.
    err.fileName = err.file;
    err.loc = {
      line: err.line,
      column: err.column
    };
    throw err;
  }
  asset.type = 'css';
  asset.setCode(css);
}
function resolvePathImporter({
  asset,
  resolve,
  loadPaths,
  indentedSyntax,
  options
}) {
  return {
    // This is a reimplementation of the Sass resolution algorithm that uses Parcel's
    // FS and tracks all tried files so they are watched for creation.
    async canonicalize(url, {
      containingUrl
    }) {
      /*
        Imports are resolved by trying, in order:
          * Loading a file relative to the file in which the `@import` appeared.
          * Each custom importer.
          * Loading a file relative to the current working directory (This rule doesn't really make sense for Parcel).
          * Each load path in `includePaths`
          * Each load path specified in the `SASS_PATH` environment variable, which should be semicolon-separated on Windows and colon-separated elsewhere.
         See: https://sass-lang.com/documentation/js-api#importer
        See also: https://github.com/sass/dart-sass/blob/006e6aa62f2417b5267ad5cdb5ba050226fab511/lib/src/importer/node/implementation.dart
      */

      let containingPath = containingUrl ? (0, _url().fileURLToPath)(containingUrl) : asset.filePath;
      if (!containingUrl && url.startsWith('file:')) {
        // If containingUrl is not provided, then url should be an absolute file:/// URL.
        let filePath = (0, _url().fileURLToPath)(url);
        url = _path().default.relative(_path().default.dirname(containingPath), filePath);
      }
      let paths = [_path().default.dirname(containingPath)];
      if (loadPaths) {
        paths.push(...loadPaths);
      }
      asset.invalidateOnEnvChange('SASS_PATH');
      if (options.env.SASS_PATH) {
        paths.push(...options.env.SASS_PATH.split(process.platform === 'win32' ? ';' : ':').map(p => _path().default.resolve(options.projectRoot, p)));
      }

      // The importer should look for stylesheets by adding the prefix _ to the URL's basename,
      // and by adding the extensions .sass and .scss if the URL doesn't already have one of those extensions.
      const urls = [url];
      const urlFileName = _path().default.basename(url);
      if (urlFileName[0] !== '_') {
        urls.push(_path().default.posix.join(_path().default.dirname(url), `_${urlFileName}`));
      }
      let ext = _path().default.extname(urlFileName);
      if (ext !== '.sass' && ext !== '.scss') {
        for (let url of [...urls]) {
          urls.push(url + '.sass');
          urls.push(url + '.scss');
        }
      }

      // If none of the possible paths is valid, the importer should perform the same resolution on the URL followed by /index.
      urls.push(_path().default.posix.join(url, 'index.sass'));
      urls.push(_path().default.posix.join(url, 'index.scss'));
      urls.push(_path().default.posix.join(url, '_index.sass'));
      urls.push(_path().default.posix.join(url, '_index.scss'));
      if (url[0] !== '~') {
        for (let p of paths) {
          for (let u of urls) {
            var _stat;
            let filePath = _path().default.resolve(p, u);
            let stat;
            try {
              stat = await asset.fs.stat(filePath);
            } catch (err) {
              // ignore.
            }
            if ((_stat = stat) !== null && _stat !== void 0 && _stat.isFile()) {
              return (0, _url().pathToFileURL)(filePath);
            }
            asset.invalidateOnFileCreate({
              filePath
            });
          }
        }
      }

      // If none of the default sass rules apply, try Parcel's resolver.
      for (let u of urls) {
        if (NODE_MODULE_ALIAS_RE.test(u)) {
          u = u.slice(1);
        }
        try {
          const filePath = await resolve(containingPath, u, {
            packageConditions: ['sass', 'style']
          });
          return (0, _url().pathToFileURL)(filePath);
        } catch (err) {
          continue;
        }
      }
    },
    async load(url) {
      let path = (0, _url().fileURLToPath)(url);
      const contents = await asset.fs.readFile(path, 'utf8');
      return {
        contents,
        syntax: (indentedSyntax != null ? indentedSyntax : (0, _path().extname)(path) === '.sass') ? 'indented' : 'scss'
      };
    }
  };
}