"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.printBlocks = printBlocks;
exports.gitUpdate = gitUpdate;
exports.gitClone = gitClone;
exports.routeExists = routeExists;
exports.fetchUmiBlock = fetchUmiBlock;
exports.fetchBlockList = exports.depthRouterConfig = exports.genComponentToTreeData = exports.genRouterToTreeData = exports.addRoutePrefix = exports.removePrefix = exports.reduceData = exports.getBlockListFromGit = exports.imgFilter = exports.genBlockName = void 0;

function _react() {
  const data = _interopRequireDefault(require("react"));

  _react = function _react() {
    return data;
  };

  return data;
}

function _chalk() {
  const data = _interopRequireDefault(require("chalk"));

  _chalk = function _chalk() {
    return data;
  };

  return data;
}

function _path() {
  const data = require("path");

  _path = function _path() {
    return data;
  };

  return data;
}

function _fs() {
  const data = require("fs");

  _fs = function _fs() {
    return data;
  };

  return data;
}

function _execa() {
  const data = _interopRequireDefault(require("execa"));

  _execa = function _execa() {
    return data;
  };

  return data;
}

function _ora() {
  const data = _interopRequireDefault(require("ora"));

  _ora = function _ora() {
    return data;
  };

  return data;
}

function _gitUrlParse() {
  const data = _interopRequireDefault(require("git-url-parse"));

  _gitUrlParse = function _gitUrlParse() {
    return data;
  };

  return data;
}

function _terminalLink() {
  const data = _interopRequireDefault(require("terminal-link"));

  _terminalLink = function _terminalLink() {
    return data;
  };

  return data;
}

function _umiUtils() {
  const data = require("umi-utils");

  _umiUtils = function _umiUtils() {
    return data;
  };

  return data;
}

var _arrayToTree = _interopRequireDefault(require("./arrayToTree"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

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; }

/**
 * 全局使用的 loading
 */
const spinner = (0, _ora().default)();
/**
 * 判断是不是一个 gitmodules 的仓库
 */

const isSubmodule = templateTmpDirPath => (0, _fs().existsSync)((0, _path().join)(templateTmpDirPath, '.gitmodules'));
/**
 * * 预览专用 *
 * 从文件数组映射为 pro 的路由
 * @param {*} name
 */


const genBlockName = name => name.match(/[A-Z]?[a-z]+|[0-9]+/g).map(p => p.toLowerCase()).join('/');
/**
 * 将区块转化为 inquirer 能用的数组
 * @param {*} blocks
 * @returns {[
 *  name:string;
 *  value:string;
 *  key:string;
 * ]} blockArray
 */


exports.genBlockName = genBlockName;

function printBlocks(blocks, hasLink) {
  const blockArray = [];

  const loopBlocks = (blockItems, parentPath = '') => {
    blockItems.forEach(block => {
      if (block.type === 'block') {
        const blockName = (0, _path().join)(parentPath, block.path);
        const previewUrl = block.previewUrl;
        let name = `📦  ${_chalk().default.cyan(blockName)}  `;

        if (hasLink) {
          // 链接到 pro 的预览界面
          // AccountCenter -> account/center
          const link = (0, _terminalLink().default)('预览', `https://preview.pro.ant.design/${previewUrl}`); // 增加一个预览的界面

          name += link;
        }

        blockArray.push({
          name,
          value: blockName,
          key: blockName
        });
      }

      if (block.type === 'dir') {
        return loopBlocks(block.blocks, block.path);
      }

      return null;
    });
  };

  loopBlocks(blocks);
  return blockArray;
} // https://gitee.com/ant-design/pro-blocks/raw/master/AccountCenter/snapshot.png
// https://raw.githubusercontent.com/ant-design/pro-blocks/master/AccountCenter/snapshot.png?raw=true


const imgFilter = (list, {
  name,
  owner
}, useGitee) => {
  if (!useGitee) {
    return list;
  }

  return list.map(item => _objectSpread({}, item, {
    img: item.img.replace(`https://raw.githubusercontent.com/${owner}/${name}/master/`, `https://gitee.com/${owner}/${name}/raw/master/`)
  }));
};

exports.imgFilter = imgFilter;

const getBlockListFromGit = /*#__PURE__*/function () {
  var _ref = _asyncToGenerator(function* (gitUrl, useBuiltJSON) {
    const got = require('got');

    const ignoreFile = ['_scripts', 'tests'];

    const _GitUrlParse = (0, _gitUrlParse().default)(gitUrl),
          name = _GitUrlParse.name,
          owner = _GitUrlParse.owner,
          resource = _GitUrlParse.resource;

    if (spinner.isSpinning) {
      spinner.succeed();
    }

    if (useBuiltJSON) {
      const fastGithub = yield (0, _umiUtils().getFastGithub)(); // use blockList.json in git repo

      const url = fastGithub === 'gitee.com' ? `https://gitee.com/${owner}/${name}/raw/master/umi-block.json` : `https://raw.githubusercontent.com/${owner}/${name}/master/umi-block.json`;
      spinner.start(`🔍  find block list form ${_chalk().default.yellow(url)}`);

      try {
        const _yield$got = yield got(url),
              body = _yield$got.body;

        spinner.succeed(); // body = {blocks: [], templates: []}

        const data = JSON.parse(body); // TODO update format logic

        return imgFilter(data.list || data.blocks || data.template, {
          name,
          owner
        }, fastGithub === 'gitee.com');
      } catch (error) {// if file 404
      }

      return [];
    } // 如果不是 github 不支持这个方法，返回一个空
    // 可以搞一些约定，下次 下次


    if (resource !== 'github.com') {
      return [];
    } // 一个 github 的 api,可以获得文件树


    const url = `https://api.github.com/repos/${owner}/${name}/git/trees/master`;
    spinner.start(`🔍  find block list form ${_chalk().default.yellow(url)}`);

    const _yield$got2 = yield got(url),
          body = _yield$got2.body;

    const filesTree = JSON.parse(body).tree.filter(file => file.type === 'tree' && !ignoreFile.includes(file.path) && file.path.indexOf('.') !== 0).map(({
      path
    }) => ({
      url: `${gitUrl}/tree/master/${path}`,
      type: 'block',
      path,
      isPage: true,
      defaultPath: `/${path}`,
      img: `https://github.com/ant-design/pro-blocks/raw/master/${path}/snapshot.png`,
      tags: ['Ant Design Pro'],
      name: path,
      previewUrl: `https://preview.pro.ant.design/${genBlockName(path)}`
    }));
    spinner.succeed();
    return filesTree;
  });

  return function getBlockListFromGit(_x, _x2) {
    return _ref.apply(this, arguments);
  };
}();
/**
 * clone 下来的 git 会缓存。这个方法可以更新缓存
 * @param {*} ctx
 * @param {*} mySpinner
 */


exports.getBlockListFromGit = getBlockListFromGit;

function gitUpdate(_x3, _x4) {
  return _gitUpdate.apply(this, arguments);
}
/**
 * 打平 children
 * {
 *    path:"/user",
 *    children:[{ path: "/user/list" }]
 *  }
 *  --->
 *  /user /user/list
 * @param treeData
 */


function _gitUpdate() {
  _gitUpdate = _asyncToGenerator(function* (ctx, mySpinner) {
    mySpinner.start('🚒  Git fetch');

    try {
      yield (0, _execa().default)('git', ['fetch'], {
        cwd: ctx.templateTmpDirPath,
        stdio: 'inherit'
      });
    } catch (e) {
      mySpinner.fail();
      throw new Error(e);
    }

    mySpinner.succeed();
    mySpinner.start(`🚛  Git checkout ${ctx.branch}`);

    try {
      yield (0, _execa().default)('git', ['checkout', ctx.branch], {
        cwd: ctx.templateTmpDirPath,
        stdio: 'inherit'
      });
    } catch (e) {
      mySpinner.fail();
      throw new Error(e);
    }

    mySpinner.succeed();
    mySpinner.start('🚀  Git pull');

    try {
      yield (0, _execa().default)('git', ['pull'], {
        cwd: ctx.templateTmpDirPath,
        stdio: 'inherit'
      }); // 如果是 git pull 之后有了
      // git module 只能通过这种办法来初始化一下

      if (isSubmodule(ctx.templateTmpDirPath)) {
        // 结束  git pull 的 spinner
        mySpinner.succeed(); // 如果是分支切换过来，可能没有初始化，初始化一下

        yield (0, _execa().default)('git', ['submodule', 'init'], {
          cwd: ctx.templateTmpDirPath,
          env: process.env,
          stdio: 'inherit'
        });
        mySpinner.start('👀  update submodule');
        yield (0, _execa().default)('git', ['submodule', 'update', '--recursive'], {
          cwd: ctx.templateTmpDirPath,
          stdio: 'inherit'
        });
      }
    } catch (e) {
      mySpinner.fail();
      throw new Error(e);
    }

    mySpinner.succeed();
  });
  return _gitUpdate.apply(this, arguments);
}

const reduceData = treeData => treeData.reduce((pre, current) => {
  const router = pre[current.key];
  let childrenKeys = {};

  if (current && current.children) {
    childrenKeys = reduceData(current.children);
  }

  if (!router) {
    pre[current.key] = _objectSpread({}, current, {
      children: undefined
    });
    delete pre[current.key].children;
  }

  return _objectSpread({}, pre, {}, childrenKeys);
}, {});
/**
 * 克隆区块的地址
 * @param {*} ctx
 * @param {*} mySpinner
 */


exports.reduceData = reduceData;

function gitClone(_x5, _x6) {
  return _gitClone.apply(this, arguments);
}
/**
 * 删除重复的下划线什么的
 * @param path
 */


function _gitClone() {
  _gitClone = _asyncToGenerator(function* (ctx, mySpinner) {
    mySpinner.start(`🔍  clone git repo from ${ctx.repo}`);

    try {
      yield (0, _execa().default)('git', ['clone', ctx.repo, ctx.id, '--recurse-submodules'], {
        cwd: ctx.blocksTempPath,
        env: process.env,
        stdio: 'inherit'
      });
    } catch (e) {
      mySpinner.fail();
      throw new Error(e);
    }

    mySpinner.succeed();
  });
  return _gitClone.apply(this, arguments);
}

const removePrefix = path => path.replace(/\//g, '/').replace(/\/\//g, '/');
/**
 * 增加路由前缀
 * data -> /data
 * @param path
 * @param parentPath
 */


exports.removePrefix = removePrefix;

const addRoutePrefix = (path = '/', parentPath = '/') => {
  if (path.indexOf('/') !== 0) {
    return removePrefix(`${parentPath}/${path}`);
  }

  return path;
};

exports.addRoutePrefix = addRoutePrefix;

const genRouterToTreeData = (routes, path = '/') => routes.map(item => {
  const prefixPath = addRoutePrefix(item.path, path);

  if (item.path || item.routes) {
    return {
      title: removePrefix(prefixPath.replace(path, '')) || '/',
      value: prefixPath,
      key: prefixPath,
      children: genRouterToTreeData(item.routes || [], prefixPath)
    };
  }

  return undefined;
}).filter(item => item);
/**
 * 根据 router 来获取  component
 * 用于区块的插入
 * @param {*} routes
 */


exports.genRouterToTreeData = genRouterToTreeData;

const genComponentToTreeData = (routes, path = '/') => routes.map(item => {
  const prefixPath = addRoutePrefix(item.path, path);
  return item.path || item.routes || item.component ? {
    title: removePrefix(prefixPath.replace(path, '/')) || '/',
    value: item.component ? item.component.replace(/(index)?((\.js?)|(\.tsx?)|(\.jsx?))$/, '') : '',
    key: prefixPath,
    children: genComponentToTreeData(item.routes || [], prefixPath)
  } : undefined;
}).filter(item => item);
/**
 * 判断路由是否存在
 * @param {*} path string
 * @param {*} routes
 */


exports.genComponentToTreeData = genComponentToTreeData;

function routeExists(path, routes = []) {
  const routerConfig = reduceData(genRouterToTreeData(routes));

  if (routerConfig[path]) {
    return true;
  }

  return false;
}
/**
 * 获取路由的数据
 * @param {*} routes
 */


const depthRouterConfig = routerConfig => {
  const getParentKey = (key = '') => {
    const routerKeyArray = key.split('/').filter(routerKey => routerKey);
    routerKeyArray.pop();
    return `/${routerKeyArray.join('/')}`;
  };

  return (0, _arrayToTree.default)(Object.keys(routerConfig).sort((a, b) => a.split('/').length - b.split('/').length + a.length - b.length).map(key => {
    const parentKey = getParentKey(key);
    return _objectSpread({}, routerConfig[key], {
      parentKey: parentKey === '/' ? null : parentKey
    });
  }), {
    id: 'key',
    parentId: 'parentKey',
    dataField: null
  });
};

exports.depthRouterConfig = depthRouterConfig;

/**
 * get BlockList from blockList.json in github repo
 */
const fetchBlockList = /*#__PURE__*/function () {
  var _ref2 = _asyncToGenerator(function* (repo) {
    try {
      const blocks = yield getBlockListFromGit(`https://github.com/${repo}`, true);
      return {
        data: blocks,
        success: true
      };
    } catch (error) {
      return {
        message: error.message,
        data: undefined,
        success: false
      };
    }
  });

  return function fetchBlockList(_x7) {
    return _ref2.apply(this, arguments);
  };
}();

exports.fetchBlockList = fetchBlockList;

function fetchUmiBlock(_x8) {
  return _fetchUmiBlock.apply(this, arguments);
}

function _fetchUmiBlock() {
  _fetchUmiBlock = _asyncToGenerator(function* (url) {
    try {
      const got = require('got');

      const _yield$got3 = yield got(url),
            body = _yield$got3.body;

      return {
        data: JSON.parse(body).list,
        success: true
      };
    } catch (error) {
      return {
        message: error.message,
        data: undefined,
        success: false
      };
    }
  });
  return _fetchUmiBlock.apply(this, arguments);
}