text: "use strict";
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.default = void 0;
  
  function _micromatch() {
    const data = require("micromatch");
  
    _micromatch = function () {
      return data;
    };
  
    return data;
  }
  
  function _path() {
    const data = require("path");
  
    _path = function () {
      return data;
    };
  
    return data;
  }
  
  function _loadParcelPlugin() {
    const data = _interopRequireDefault(require("./loadParcelPlugin"));
  
    _loadParcelPlugin = function () {
      return data;
    };
  
    return data;
  }
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  
  class ParcelConfig {
    constructor(config, options) {
      _defineProperty(this, "options", void 0);
  
      _defineProperty(this, "filePath", void 0);
  
      _defineProperty(this, "resolvers", void 0);
  
      _defineProperty(this, "transformers", void 0);
  
      _defineProperty(this, "bundler", void 0);
  
      _defineProperty(this, "namers", void 0);
  
      _defineProperty(this, "runtimes", void 0);
  
      _defineProperty(this, "packagers", void 0);
  
      _defineProperty(this, "validators", void 0);
  
      _defineProperty(this, "optimizers", void 0);
  
      _defineProperty(this, "reporters", void 0);
  
      _defineProperty(this, "pluginCache", void 0);
  
      _defineProperty(this, "regexCache", void 0);
  
      this.options = options;
      this.filePath = config.filePath;
      this.resolvers = config.resolvers || [];
      this.transformers = config.transformers || {};
      this.runtimes = config.runtimes || {};
      this.bundler = config.bundler;
      this.namers = config.namers || [];
      this.packagers = config.packagers || {};
      this.optimizers = config.optimizers || {};
      this.reporters = config.reporters || [];
      this.validators = config.validators || {};
      this.pluginCache = new Map();
      this.regexCache = new Map();
    }
  
    static deserialize(serialized) {
      return new ParcelConfig(serialized.config, serialized.options);
    }
  
    getConfig() {
      return {
        filePath: this.filePath,
        resolvers: this.resolvers,
        transformers: this.transformers,
        validators: this.validators,
        runtimes: this.runtimes,
        bundler: this.bundler,
        namers: this.namers,
        packagers: this.packagers,
        optimizers: this.optimizers,
        reporters: this.reporters
      };
    }
  
    serialize() {
      return {
        $$raw: false,
        config: this.getConfig(),
        options: this.options
      };
    }
  
    loadPlugin(node) {
      let plugin = this.pluginCache.get(node.packageName);
  
      if (plugin) {
        return plugin;
      }
  
      plugin = (0, _loadParcelPlugin().default)(node.packageName, node.resolveFrom, node.keyPath, this.options);
      this.pluginCache.set(node.packageName, plugin);
      return plugin;
    }
  
    loadPlugins(plugins) {
      return Promise.all(plugins.map(async p => {
        let {
          plugin,
          version
        } = await this.loadPlugin(p);
        return {
          name: p.packageName,
          plugin,
          version,
          resolveFrom: p.resolveFrom,
          keyPath: p.keyPath
        };
      }));
    }
  
    _getResolverNodes() {
      if (this.resolvers.length === 0) {
        throw new Error('No resolver plugins specified in .parcelrc config');
      }
  
      return this.resolvers;
    }
  
    getResolverNames() {
      return this._getResolverNodes().map(r => r.packageName);
    }
  
    getResolvers() {
      return this.loadPlugins(this._getResolverNodes());
    }
  
    _getValidatorNodes(filePath) {
      let validators = this.matchGlobMapPipelines(filePath, this.validators) || [];
      return validators;
    }
  
    getValidatorNames(filePath) {
      let validators = this._getValidatorNodes(filePath);
  
      return validators.map(v => v.packageName);
    }
  
    getValidators(filePath) {
      let validators = this._getValidatorNodes(filePath);
  
      return this.loadPlugins(validators);
    }
  
    getNamedPipelines() {
      return Object.keys(this.transformers).filter(glob => glob.includes(':')).map(glob => glob.split(':')[0]);
    }
  
    _getTransformerNodes(filePath, pipeline, allowEmpty) {
      let transformers = this.matchGlobMapPipelines(filePath, this.transformers, pipeline);
  
      if (!transformers || transformers.length === 0) {
        if (allowEmpty) {
          return [];
        }
  
        throw new Error(`No transformers found for ${filePath}` + (pipeline != null ? ` with pipeline: '${pipeline}'` : '') + '.');
      }
  
      return transformers;
    }
  
    getTransformerNames(filePath, pipeline, allowEmpty) {
      let transformers = this._getTransformerNodes(filePath, pipeline, allowEmpty);
  
      return transformers.map(t => t.packageName);
    }
  
    getTransformers(filePath, pipeline, allowEmpty) {
      return this.loadPlugins(this._getTransformerNodes(filePath, pipeline, allowEmpty));
    }
  
    getBundlerName() {
      if (!this.bundler) {
        throw new Error('No bundler specified in .parcelrc config');
      }
  
      return this.bundler.packageName;
    }
  
    getBundler() {
      if (!this.bundler) {
        throw new Error('No bundler specified in .parcelrc config');
      }
  
      return this.loadPlugin(this.bundler);
    }
  
    getNamers() {
      if (this.namers.length === 0) {
        throw new Error('No namer plugins specified in .parcelrc config');
      }
  
      return this.loadPlugins(this.namers);
    }
  
    getRuntimes(context) {
      let runtimes = this.runtimes[context];
  
      if (!runtimes) {
        return Promise.resolve([]);
      }
  
      return this.loadPlugins(runtimes);
    }
  
    _getPackagerNode(filePath) {
      let packagerName = this.matchGlobMap(filePath, this.packagers);
  
      if (!packagerName) {
        throw new Error(`No packager found for "${filePath}".`);
      }
  
      return packagerName;
    }
  
    getPackagerName(filePath) {
      return this._getPackagerNode(filePath).packageName;
    }
  
    async getPackager(filePath) {
      let packager = this._getPackagerNode(filePath);
  
      let {
        plugin,
        version
      } = await this.loadPlugin(packager);
      return {
        name: packager.packageName,
        version,
        plugin
      };
    }
  
    _getOptimizerNodes(filePath, pipeline) {
      var _this$matchGlobMapPip;
  
      return (_this$matchGlobMapPip = this.matchGlobMapPipelines(filePath, this.optimizers, pipeline)) !== null && _this$matchGlobMapPip !== void 0 ? _this$matchGlobMapPip : [];
    }
  
    getOptimizerNames(filePath, pipeline) {
      let optimizers = this._getOptimizerNodes(filePath, pipeline);
  
      return optimizers.map(o => o.packageName);
    }
  
    getOptimizers(filePath, pipeline) {
      let optimizers = this._getOptimizerNodes(filePath, pipeline);
  
      if (optimizers.length === 0) {
        return Promise.resolve([]);
      }
  
      return this.loadPlugins(optimizers);
    }
  
    getReporters() {
      return this.loadPlugins(this.reporters);
    }
  
    isGlobMatch(filePath, pattern, pipeline) {
      let [patternPipeline, patternGlob] = pattern.split(':');
  
      if (!patternGlob) {
        patternGlob = patternPipeline;
        patternPipeline = null;
      }
  
      let re = this.regexCache.get(patternGlob);
  
      if (!re) {
        re = (0, _micromatch().makeRe)(patternGlob, {
          dot: true
        });
        this.regexCache.set(patternGlob, re);
      }
  
      return (pipeline === patternPipeline || !pipeline && !patternPipeline) && (re.test(filePath) || re.test((0, _path().basename)(filePath)));
    }
  
    matchGlobMap(filePath, globMap) {
      for (let pattern in globMap) {
        if (this.isGlobMatch(filePath, pattern)) {
          return globMap[pattern];
        }
      }
  
      return null;
    }
  
    matchGlobMapPipelines(filePath, globMap, pipeline) {
      let matches = [];
  
      if (pipeline) {
        // If a pipeline is requested, a the glob needs to match exactly
        let exactMatch;
  
        for (let pattern in globMap) {
          if (this.isGlobMatch(filePath, pattern, pipeline)) {
            exactMatch = globMap[pattern];
            break;
          }
        }
  
        if (!exactMatch) {
          return [];
        } else {
          matches.push(exactMatch);
        }
      }
  
      for (let pattern in globMap) {
        if (this.isGlobMatch(filePath, pattern)) {
          matches.push(globMap[pattern]);
        }
      }
  
      let flatten = () => {
        let pipeline = matches.shift() || [];
        let spreadIndex = pipeline.indexOf('...');
  
        if (spreadIndex >= 0) {
          pipeline = [...pipeline.slice(0, spreadIndex), ...flatten(), ...pipeline.slice(spreadIndex + 1)];
        }
  
        if (pipeline.includes('...')) {
          throw new Error('Only one spread parameter can be included in a config pipeline');
        }
  
        return pipeline;
      };
  
      let res = flatten(); // $FlowFixMe afaik this should work
  
      return res;
    }
  
  }
  
  exports.default = ParcelConfig;