text: /**
   * Copyright (c) Facebook, Inc. and its affiliates.
   *
   * This source code is licensed under the MIT license found in the
   * LICENSE file in the root directory of this source tree.
   *
   * @flow
   * @format
   */
  
  'use strict';
  
  const nullthrows = require('nullthrows');
  const path = require('path');
  
  import type {PackageData} from '../types.flow';
  
  module.exports = class Package {
    data: PackageData;
    path: string;
    root: string;
    type: 'Package';
  
    constructor(packagePath: string, data: PackageData) {
      this.data = data;
      this.path = packagePath;
      this.root = path.dirname(packagePath);
      this.type = 'Package';
    }
  
    getMain(): string {
      // Copied from node-haste/Package.js
      const replacements = getReplacements(this.data);
      if (typeof replacements === 'string') {
        return path.join(this.root, replacements);
      }
  
      let main = getMain(this.data);
  
      if (replacements && typeof replacements === 'object') {
        main =
          replacements[main] ||
          replacements[main + '.js'] ||
          replacements[main + '.json'] ||
          replacements[main.replace(/(\.js|\.json)$/, '')] ||
          main;
      }
  
      return path.join(this.root, main);
    }
  
    getName(): string {
      return nullthrows(this.data.name);
    }
  
    isHaste(): boolean {
      return !!this.data.name;
    }
  
    redirectRequire(name: string) {
      // Copied from node-haste/Package.js
      const replacements = getReplacements(this.data);
  
      if (!replacements || typeof replacements !== 'object') {
        return name;
      }
  
      if (!path.isAbsolute(name)) {
        const replacement = replacements[name];
        // support exclude with "someDependency": false
        return replacement === false ? false : replacement || name;
      }
  
      let relPath = './' + path.relative(this.root, name);
      if (path.sep !== '/') {
        relPath = relPath.replace(new RegExp('\\' + path.sep, 'g'), '/');
      }
  
      let redirect = replacements[relPath];
  
      // false is a valid value
      if (redirect == null) {
        redirect = replacements[relPath + '.js'];
        if (redirect == null) {
          redirect = replacements[relPath + '.json'];
        }
      }
  
      // support exclude with "./someFile": false
      if (redirect === false) {
        return false;
      }
  
      if (redirect) {
        return path.join(this.root, redirect);
      }
  
      return name;
    }
  };
  
  function getMain(pkg: PackageData): string {
    return pkg.main || 'index';
  }
  
  // Copied from node-haste/Package.js
  function getReplacements(pkg: PackageData) {
    let rn = pkg['react-native'];
    let browser = pkg.browser;
    if (rn == null) {
      return browser;
    }
  
    if (browser == null) {
      return rn;
    }
  
    const main = getMain(pkg);
    if (typeof rn !== 'object') {
      rn = {[main]: rn};
    }
  
    if (typeof browser !== 'object') {
      browser = {[main]: browser};
    }
  
    // merge with "browser" as default,
    // "react-native" as override
    return {...browser, ...rn};
  }
  