"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

function _bluebird() {
  const data = require("bluebird");

  _bluebird = function () {
    return data;
  };

  return data;
}

function _fsExtra() {
  const data = _interopRequireDefault(require("fs-extra"));

  _fsExtra = function () {
    return data;
  };

  return data;
}

function _ramda() {
  const data = _interopRequireDefault(require("ramda"));

  _ramda = function () {
    return data;
  };

  return data;
}

function _abstractConfig() {
  const data = _interopRequireDefault(require("./abstract-config"));

  _abstractConfig = function () {
    return data;
  };

  return data;
}

function _exceptions() {
  const data = require("./exceptions");

  _exceptions = function () {
    return data;
  };

  return data;
}

function _constants() {
  const data = require("../../constants");

  _constants = function () {
    return data;
  };

  return data;
}

function _filterObject() {
  const data = _interopRequireDefault(require("../../utils/filter-object"));

  _filterObject = function () {
    return data;
  };

  return data;
}

function _logger() {
  const data = _interopRequireDefault(require("../../logger/logger"));

  _logger = function () {
    return data;
  };

  return data;
}

function _utils() {
  const data = require("../../utils");

  _utils = function () {
    return data;
  };

  return data;
}

function _invalidConfigPropPath() {
  const data = _interopRequireDefault(require("./exceptions/invalid-config-prop-path"));

  _invalidConfigPropPath = function () {
    return data;
  };

  return data;
}

function _consumerOverrides() {
  const data = _interopRequireDefault(require("./consumer-overrides"));

  _consumerOverrides = function () {
    return data;
  };

  return data;
}

function _invalidPackageManager() {
  const data = _interopRequireDefault(require("./exceptions/invalid-package-manager"));

  _invalidPackageManager = function () {
    return data;
  };

  return data;
}

const DEFAULT_USE_WORKSPACES = false;
const DEFAULT_MANAGE_WORKSPACES = true;
const DEFAULT_SAVE_DEPENDENCIES_AS_COMPONENTS = false;

class WorkspaceConfig extends _abstractConfig().default {
  // path where to store build artifacts
  // path to remove while storing build artifacts. If, for example the code is in 'src' directory, and the component
  // is-string is in src/components/is-string, the dists files will be in dists/component/is-string (without the 'src')
  // save hub dependencies as bit components rather than npm packages
  // package manager client to use
  // package manager client to use
  // package manager process options
  // Enables integration with Yarn Workspaces
  // manage workspaces with yarn
  // workspace package.json if exists (parsed)
  constructor({
    compiler,
    tester,
    saveDependenciesAsComponents = DEFAULT_SAVE_DEPENDENCIES_AS_COMPONENTS,
    lang,
    distTarget,
    distEntry,
    componentsDefaultDirectory = _constants().DEFAULT_COMPONENTS_DIR_PATH,
    dependenciesDirectory = _constants().DEFAULT_DEPENDENCIES_DIR_PATH,
    ejectedEnvsDirectory = _constants().DEFAULT_EJECTED_ENVS_DIR_PATH,
    bindingPrefix,
    extensions,
    packageManager = _constants().DEFAULT_PACKAGE_MANAGER,
    packageManagerArgs,
    packageManagerProcessOptions,
    useWorkspaces = DEFAULT_USE_WORKSPACES,
    manageWorkspaces = DEFAULT_MANAGE_WORKSPACES,
    resolveModules,
    overrides = _consumerOverrides().default.load()
  }) {
    super({
      compiler,
      tester,
      lang,
      bindingPrefix,
      extensions
    });

    if (packageManager !== 'npm' && packageManager !== 'yarn') {
      throw new (_invalidPackageManager().default)(packageManager);
    }

    this.distTarget = distTarget;
    this.distEntry = distEntry;
    this.componentsDefaultDirectory = componentsDefaultDirectory; // Make sure we have the component name in the path. otherwise components will be imported to the same dir.

    if (!componentsDefaultDirectory.includes('{name}')) {
      this.componentsDefaultDirectory = `${this.componentsDefaultDirectory}/{name}`;
    }

    this.dependenciesDirectory = dependenciesDirectory;
    this.ejectedEnvsDirectory = ejectedEnvsDirectory;
    this.saveDependenciesAsComponents = saveDependenciesAsComponents;
    this.packageManager = packageManager;
    this.packageManagerArgs = packageManagerArgs;
    this.packageManagerProcessOptions = packageManagerProcessOptions;
    this.useWorkspaces = useWorkspaces;
    this.manageWorkspaces = manageWorkspaces;
    this.resolveModules = resolveModules;
    this.overrides = overrides;
  }

  toPlainObject() {
    const superObject = super.toPlainObject();

    let consumerObject = _ramda().default.merge(superObject, {
      componentsDefaultDirectory: this.componentsDefaultDirectory,
      dependenciesDirectory: this.dependenciesDirectory,
      ejectedEnvsDirectory: this.ejectedEnvsDirectory,
      saveDependenciesAsComponents: this.saveDependenciesAsComponents,
      packageManager: this.packageManager,
      packageManagerArgs: this.packageManagerArgs,
      packageManagerProcessOptions: this.packageManagerProcessOptions,
      useWorkspaces: this.useWorkspaces,
      manageWorkspaces: this.manageWorkspaces,
      resolveModules: this.resolveModules,
      overrides: this.overrides.overrides
    });

    if (this.distEntry || this.distTarget) {
      const dist = {};
      if (this.distEntry) dist.entry = this.distEntry;
      if (this.distTarget) dist.target = this.distTarget;
      consumerObject = _ramda().default.merge(consumerObject, {
        dist
      });
    }

    const isPropDefault = (val, key) => {
      if (key === 'dependenciesDirectory') return val !== _constants().DEFAULT_DEPENDENCIES_DIR_PATH;
      if (key === 'ejectedEnvsDirectory') return val !== _constants().DEFAULT_EJECTED_ENVS_DIR_PATH;
      if (key === 'useWorkspaces') return val !== DEFAULT_USE_WORKSPACES;
      if (key === 'manageWorkspaces') return val !== DEFAULT_MANAGE_WORKSPACES;
      if (key === 'saveDependenciesAsComponents') return val !== DEFAULT_SAVE_DEPENDENCIES_AS_COMPONENTS;
      if (key === 'resolveModules') return !_ramda().default.isEmpty(val);
      if (key === 'overrides') return !_ramda().default.isEmpty(val);
      return true;
    };

    return (0, _filterObject().default)(consumerObject, isPropDefault);
  }

  static create(workspaceConfigProps) {
    return new WorkspaceConfig(workspaceConfigProps);
  }

  static ensure(dirPath, standAlone, workspaceConfigProps = {}) {
    var _this = this;

    return (0, _bluebird().coroutine)(function* () {
      try {
        const workspaceConfig = yield _this.load(dirPath);
        return workspaceConfig;
      } catch (err) {
        if (err instanceof _exceptions().BitConfigNotFound || err instanceof _exceptions().InvalidBitJson) {
          const consumerBitJson = _this.create(workspaceConfigProps);

          const packageJsonExists = yield _abstractConfig().default.pathHasPackageJson(dirPath);

          if (packageJsonExists && !standAlone) {
            consumerBitJson.writeToPackageJson = true;
          } else {
            consumerBitJson.writeToBitJson = true;
          }

          return consumerBitJson;
        }

        throw err;
      }
    })();
  }

  static reset(dirPath, resetHard) {
    return (0, _bluebird().coroutine)(function* () {
      const deleteBitJsonFile =
      /*#__PURE__*/
      function () {
        var _ref = (0, _bluebird().coroutine)(function* () {
          const bitJsonPath = _abstractConfig().default.composeBitJsonPath(dirPath);

          _logger().default.info(`deleting the consumer bit.json file at ${bitJsonPath}`);

          yield _fsExtra().default.remove(bitJsonPath);
        });

        return function deleteBitJsonFile() {
          return _ref.apply(this, arguments);
        };
      }();

      if (resetHard) yield deleteBitJsonFile();
    })();
  }

  static fromPlainObject(object) {
    WorkspaceConfig.validate(object);
    const {
      env,
      lang,
      componentsDefaultDirectory,
      dependenciesDirectory,
      ejectedEnvsDirectory,
      dist,
      bindingPrefix,
      extensions,
      saveDependenciesAsComponents,
      packageManager,
      packageManagerArgs,
      packageManagerProcessOptions,
      useWorkspaces,
      manageWorkspaces,
      resolveModules,
      overrides
    } = object;
    return new WorkspaceConfig({
      compiler: _ramda().default.propOr(undefined, 'compiler', env),
      tester: _ramda().default.propOr(undefined, 'tester', env),
      lang,
      bindingPrefix,
      extensions,
      saveDependenciesAsComponents,
      componentsDefaultDirectory,
      dependenciesDirectory,
      ejectedEnvsDirectory,
      packageManager,
      packageManagerArgs,
      packageManagerProcessOptions,
      useWorkspaces,
      manageWorkspaces,
      resolveModules,
      distTarget: _ramda().default.propOr(undefined, 'target', dist),
      distEntry: _ramda().default.propOr(undefined, 'entry', dist),
      overrides: _consumerOverrides().default.load(overrides)
    });
  }

  static load(dirPath) {
    var _this2 = this;

    return (0, _bluebird().coroutine)(function* () {
      const bitJsonPath = _abstractConfig().default.composeBitJsonPath(dirPath);

      const packageJsonPath = _abstractConfig().default.composePackageJsonPath(dirPath);

      const [bitJsonFile, packageJsonFile] = yield Promise.all([_this2.loadBitJson(bitJsonPath), // $FlowFixMe
      _this2.loadPackageJson(packageJsonPath)]);
      const bitJsonConfig = bitJsonFile || {};
      const packageJsonHasConfig = packageJsonFile && packageJsonFile.bit;
      const packageJsonConfig = packageJsonHasConfig ? packageJsonFile.bit : {};
      if (_ramda().default.isEmpty(bitJsonConfig) && _ramda().default.isEmpty(packageJsonConfig)) throw new (_exceptions().BitConfigNotFound)(); // in case of conflicts, bit.json wins package.json

      const config = Object.assign(packageJsonConfig, bitJsonConfig);

      const workspaceConfig = _this2.fromPlainObject(config);

      workspaceConfig.path = bitJsonPath;
      workspaceConfig.writeToBitJson = Boolean(bitJsonFile);
      workspaceConfig.writeToPackageJson = packageJsonHasConfig;
      workspaceConfig.packageJsonObject = packageJsonFile;
      return workspaceConfig;
    })();
  }

  static loadBitJson(bitJsonPath) {
    return (0, _bluebird().coroutine)(function* () {
      try {
        const file = yield _abstractConfig().default.loadJsonFileIfExist(bitJsonPath);
        return file;
      } catch (e) {
        throw new (_exceptions().InvalidBitJson)(bitJsonPath);
      }
    })();
  }

  static loadPackageJson(packageJsonPath) {
    return (0, _bluebird().coroutine)(function* () {
      try {
        const file = yield _abstractConfig().default.loadJsonFileIfExist(packageJsonPath);
        return file;
      } catch (e) {
        throw new (_exceptions().InvalidPackageJson)(packageJsonPath);
      }
    })();
  }

  static validate(object) {
    const {
      componentsDefaultDirectory,
      dependenciesDirectory,
      ejectedEnvsDirectory
    } = object;
    const pathsToValidate = {
      componentsDefaultDirectory,
      dependenciesDirectory,
      ejectedEnvsDirectory
    };
    Object.keys(pathsToValidate).forEach(field => throwForInvalidPath(field, pathsToValidate[field]));

    function throwForInvalidPath(fieldName, pathToValidate) {
      if (pathToValidate && !(0, _utils().isValidPath)(pathToValidate)) {
        throw new (_invalidConfigPropPath().default)(fieldName, pathToValidate);
      }
    }

    _consumerOverrides().default.validate(object.overrides);
  }

}

exports.default = WorkspaceConfig;