"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.UpdateAspectCmd = exports.UnsetAspectCmd = exports.SetAspectCmd = exports.ListCoreAspectCmd = exports.ListAspectCmd = exports.GetAspectCmd = exports.AspectCmd = void 0;
function _cliTable() {
  const data = require("@teambit/cli-table");
  _cliTable = function () {
    return data;
  };
  return data;
}
function _chalk() {
  const data = _interopRequireDefault(require("chalk"));
  _chalk = function () {
    return data;
  };
  return data;
}
function _legacy() {
  const data = require("@teambit/legacy.constants");
  _legacy = function () {
    return data;
  };
  return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } // eslint-disable-next-line max-classes-per-file
class ListAspectCmd {
  constructor(aspect) {
    this.aspect = aspect;
    _defineProperty(this, "name", 'list [pattern]');
    _defineProperty(this, "description", 'list all aspects configured on component(s)');
    _defineProperty(this, "arguments", [{
      name: 'pattern',
      description: _legacy().COMPONENT_PATTERN_HELP
    }]);
    _defineProperty(this, "options", [['d', 'debug', 'show the origins where the aspects were taken from']]);
    _defineProperty(this, "group", 'info-analysis');
  }
  async report([name], {
    debug
  }) {
    const listAspectsResults = await this.aspect.listAspectsOfComponent(name);
    const rows = Object.keys(listAspectsResults).map(componentId => {
      const longestAspectName = Math.max(...listAspectsResults[componentId].map(_ => _.aspectName.length));
      const aspects = listAspectsResults[componentId].map(aspectSource => {
        const origin = debug ? ` (origin: ${aspectSource.source})` : '';
        const aspectName = aspectSource.aspectName.padEnd(longestAspectName);
        return `${aspectName} (level: ${aspectSource.level})${origin}`;
      }).join('\n');
      return [componentId, aspects];
    });
    const table = new (_cliTable().CLITable)([], rows);
    return table.render();
  }
}
exports.ListAspectCmd = ListAspectCmd;
class ListCoreAspectCmd {
  constructor(aspect) {
    this.aspect = aspect;
    _defineProperty(this, "name", 'list-core');
    _defineProperty(this, "description", 'list all core aspects');
    _defineProperty(this, "arguments", [{
      name: 'pattern',
      description: _legacy().COMPONENT_PATTERN_HELP
    }]);
    _defineProperty(this, "options", [['j', 'json', 'format as json']]);
    _defineProperty(this, "group", 'info-analysis');
  }
  async report() {
    return this.aspect.listCoreAspects().join('\n');
  }
  async json() {
    return this.aspect.listCoreAspects();
  }
}
exports.ListCoreAspectCmd = ListCoreAspectCmd;
class SetAspectCmd {
  constructor(aspect) {
    this.aspect = aspect;
    _defineProperty(this, "name", 'set <pattern> <aspect-id> [config]');
    _defineProperty(this, "description", 'set components with an aspect to extend their development tools, metadata and (possibly) artifacts');
    _defineProperty(this, "arguments", [{
      name: 'pattern',
      description: `the components to extend. ${_legacy().COMPONENT_PATTERN_HELP}`
    }, {
      name: 'aspect-id',
      description: `the aspect's component id`
    }, {
      name: 'config',
      description: `the aspect config. enter the config as a stringified JSON (e.g. \`{"foo":"bar"}\` ). when no config is provided, an aspect is set with an empty config ({}).`
    }]);
    _defineProperty(this, "options", [['m', 'merge', 'merge with an existing config if exits. (by default, it replaces overlapping existing configs)']]);
    _defineProperty(this, "group", 'component-config');
  }
  async report([pattern, aspectId, config], options) {
    const configParsed = config ? JSON.parse(config) : {};
    const results = await this.aspect.setAspectsToComponents(pattern, aspectId, configParsed, options);
    if (!results.length) return _chalk().default.yellow(`unable to find any matching components for ${_chalk().default.bold(pattern)} pattern`);
    return _chalk().default.green(`the following component(s) have been successfully updated:\n${results.join('\n')}`);
  }
}
exports.SetAspectCmd = SetAspectCmd;
class UpdateAspectCmd {
  constructor(aspect) {
    this.aspect = aspect;
    _defineProperty(this, "name", 'update <aspect-id> [pattern]');
    _defineProperty(this, "description", 'update a version of an aspect for all or specified components');
    _defineProperty(this, "arguments", [{
      name: 'aspect-id',
      description: "the aspect's component id. optionally, add a version (id@version), otherwise will use the latest version from the remote"
    }, {
      name: 'pattern',
      description: `the components to update (defaults to all components). ${_legacy().COMPONENT_PATTERN_HELP}`
    }]);
    _defineProperty(this, "examples", [{
      cmd: "bit aspect update scope.org/aspect '**/ui/**'",
      description: 'update all components with the "ui" namespace that use scope.org/aspect, to use its latest version'
    }, {
      cmd: 'bit aspect update scope.org/aspect@2.0.0',
      description: 'update version of scope.org/aspect to version 2.0.0 for all components configured with that aspect.'
    }]);
    _defineProperty(this, "options", []);
    _defineProperty(this, "group", 'component-config');
  }
  async report([aspectId, pattern]) {
    const {
      updated,
      alreadyUpToDate
    } = await this.aspect.updateAspectsToComponents(aspectId, pattern);
    if (updated.length) {
      return _chalk().default.green(`the following component(s) have been successfully updated:\n${updated.join('\n')}`);
    }
    if (alreadyUpToDate.length) {
      return _chalk().default.green(`all ${alreadyUpToDate.length} component(s) that use this aspect are already up to date. nothing to update`);
    }
    return _chalk().default.yellow(`unable to find any components in this workspace that use ${_chalk().default.bold(aspectId)}`);
  }
}
exports.UpdateAspectCmd = UpdateAspectCmd;
class UnsetAspectCmd {
  constructor(aspect) {
    this.aspect = aspect;
    _defineProperty(this, "name", 'unset <pattern> <aspect-id>');
    _defineProperty(this, "description", `unset an aspect from component(s).`);
    _defineProperty(this, "arguments", [{
      name: 'pattern',
      description: `the components to target. ${_legacy().COMPONENT_PATTERN_HELP}`
    }, {
      name: 'aspect-id',
      description: "the aspect's component id"
    }]);
    _defineProperty(this, "options", []);
    _defineProperty(this, "group", 'component-config');
  }
  async report([pattern, aspectId]) {
    const results = await this.aspect.unsetAspectsFromComponents(pattern, aspectId);
    if (!results.length) return _chalk().default.yellow(`unable to find any matching components for ${_chalk().default.bold(pattern)} pattern`);
    return _chalk().default.green(`the following component(s) have been successfully updated:\n${results.join('\n')}`);
  }
}
exports.UnsetAspectCmd = UnsetAspectCmd;
class GetAspectCmd {
  constructor(aspect) {
    this.aspect = aspect;
    _defineProperty(this, "name", 'get <component-name>');
    _defineProperty(this, "description", 'list the aspects set on a component, as well as their configs and data');
    _defineProperty(this, "arguments", [{
      name: 'component-name',
      description: 'the component name or component id to fetch aspects for'
    }]);
    _defineProperty(this, "options", [['d', 'debug', 'show the origins where the aspects were taken from'], ['j', 'json', 'format as json']]);
    _defineProperty(this, "group", 'info-analysis');
  }
  async report([componentName], {
    debug
  }) {
    const extensionsDetailsToString = extensions => extensions.map(e => {
      const {
        name,
        data,
        config,
        extensionId
      } = e.toComponentObject();
      return `${_chalk().default.bold('name:')}   ${name || extensionId?.toString()}
${_chalk().default.bold('config:')} ${JSON.stringify(config, undefined, 2)}
${_chalk().default.bold('data:')}   ${JSON.stringify(data, undefined, 2)}
`;
    }).join('\n');
    if (debug) {
      const {
        aspects,
        extensions: mergedExtensions,
        beforeMerge
      } = await this.aspect.getAspectsOfComponentForDebugging(componentName);
      const beforeMergeOutput = beforeMerge.map(({
        origin,
        extensions,
        extraData
      }) => {
        const title = _chalk().default.green.bold(`Origin: ${origin}`);
        const details = extensionsDetailsToString(extensions);
        const moreData = extraData ? `\n${_chalk().default.bold('Extra Data:')} ${JSON.stringify(extraData, undefined, 2)}` : '';
        return `${title}\n${details}${moreData}`;
      }).join('\n\n');
      const afterMergeTitle = _chalk().default.green.bold('After merging the origins above');
      const afterMergeOutput = `${afterMergeTitle}\n${extensionsDetailsToString(mergedExtensions)}`;
      const afterFinalMergeTitle = _chalk().default.green.bold('Final - After merging the origins above and the loaded data');
      const afterFinalMergeOutput = `${afterFinalMergeTitle}\n${extensionsDetailsToString(aspects.toLegacy())}`;
      return `${beforeMergeOutput}\n\n${afterMergeOutput}\n\n\n${afterFinalMergeOutput}`;
    }
    const aspects = await this.aspect.getAspectsOfComponent(componentName);
    const extensionDataList = aspects.toLegacy();
    return extensionsDetailsToString(extensionDataList);
  }
  async json([componentName], {
    debug
  }) {
    const extensionsDetailsToObject = extensions => extensions.reduce((acc, current) => {
      const {
        name,
        data,
        config,
        extensionId
      } = current.toComponentObject();
      const aspectName = name || extensionId?.toString() || '<no-name>';
      acc[aspectName] = {
        name: aspectName,
        config,
        data
      };
      return acc;
    }, {});
    if (debug) {
      const {
        aspects,
        extensions: mergedExtensions,
        beforeMerge
      } = await this.aspect.getAspectsOfComponentForDebugging(componentName);
      const jsonObj = {};
      beforeMerge.forEach(({
        origin,
        extensions,
        extraData
      }) => {
        jsonObj[origin] = {
          extensions: extensionsDetailsToObject(extensions),
          extraData
        };
      });
      jsonObj.AfterMerge = {
        extensions: extensionsDetailsToObject(mergedExtensions)
      };
      jsonObj.FinalAfterMergeIncludeLoad = {
        extensions: extensionsDetailsToObject(aspects.toLegacy())
      };
      return jsonObj;
    }
    const aspects = await this.aspect.getAspectsOfComponent(componentName);
    return extensionsDetailsToObject(aspects.toLegacy());
  }
}
exports.GetAspectCmd = GetAspectCmd;
class AspectCmd {
  constructor() {
    _defineProperty(this, "name", 'aspect <sub-command>');
    _defineProperty(this, "alias", '');
    _defineProperty(this, "description", 'manage component aspects and their configurations');
    _defineProperty(this, "extendedDescription", `aspects provide functionality and tools for components throughout their development lifecycle.
primarily useful for inspecting aspect assignments and configurations with "bit aspect get".
rarely used for manual aspect management as most aspects are configured automatically.`);
    _defineProperty(this, "options", []);
    _defineProperty(this, "group", 'component-config');
    _defineProperty(this, "commands", []);
  }
  async report([unrecognizedSubcommand]) {
    return _chalk().default.red(`"${unrecognizedSubcommand}" is not a subcommand of "aspect", please run "bit aspect --help" to list the subcommands`);
  }
}
exports.AspectCmd = AspectCmd;

//# sourceMappingURL=aspect.cmd.js.map